1. 程式人生 > >[CodeForces - 678F] Lena and Queries 線段樹維護凸包

[CodeForces - 678F] Lena and Queries 線段樹維護凸包

d+ operator size 平面 oid == pen txt stdin

   大致題意:

      給出三種操作

        1、往平面點集中添加一個點

        2、刪除第i次添加的點

        3、給出一個q,詢問平面點集中的q*x+y的最大值

  

    首先對於每個詢問,可將z=q*x+y轉化為y=z-q*x,即過點(x,y)的斜率為-q的最大截距,很容易發現這些點只會在上凸包上,只要在

    凸包上三分即可。

    對於插入和刪除操作,對於每個點可求得其“生存周期”,即其存在於[L,R]的時間範圍內。對每個點的時間區間建線段樹,則每次詢問的

    答案即為詢問所在的區間內凸包上點中的最大值。

    

技術分享圖片
  1 #include<cstdio>
  2
#include<iostream> 3 #include<cstring> 4 #include<algorithm> 5 #include<queue> 6 #include<set> 7 #include<map> 8 #include<stack> 9 #include<time.h> 10 #include<cstdlib> 11 #include<cmath> 12 #include<list> 13 using namespace
std; 14 #define MAXN 300100 15 #define eps 1e-5 16 #define For(i,a,b) for(int i=a;i<=b;i++) 17 #define Fore(i,a,b) for(int i=a;i>=b;i--) 18 #define lson l,mid,rt<<1 19 #define rson mid+1,r,rt<<1|1 20 #define mkp make_pair 21 #define pb push_back 22 #define cr clear() 23 #define
sz size() 24 #define met(a,b) memset(a,b,sizeof(a)) 25 #define iossy ios::sync_with_stdio(false) 26 #define fr freopen 27 #define pi acos(-1.0) 28 #define Vector Point 29 const long long inf=1LL<<62; 30 const int Mod=1e9+7; 31 typedef unsigned long long ull; 32 typedef long long ll; 33 typedef pair<int,int> pii; 34 typedef pair<ll,ll> pll; 35 int dcmp(double x){ 36 if(fabs(x)<=eps) return 0; 37 return x<0?-1:1; 38 } 39 struct Point { 40 ll x,y; 41 int l,r; 42 Point(ll x=0,ll y=0) : x(x),y(y) {} 43 Point operator - (const Point &a)const{ return Point(x-a.x,y-a.y); } 44 Point operator + (const Point &a)const{ return Point(x+a.x,y+a.y); } 45 Point operator * (const double &a)const{ return Point(x*a,y*a); } 46 Point operator / (const double &a)const{ return Point(x/a,y/a); } 47 bool operator < (const Point &a)const{ if(x==a.x) return y<a.y;return x<a.x; } 48 bool operator == (const Point &a)const{ return dcmp(x-a.x)==0 && dcmp(y-a.y)==0; } 49 void read() { scanf("%lld%lld",&x,&y);} 50 void out(){cout<<"Bug: "<<x<<" "<<y<<endl;} 51 }; 52 inline ll Cross(Vector a,Vector b) { return a.x*b.y-a.y*b.x; } 53 inline double Dot(Vector a,Vector b) { return a.x*b.x+a.y*b.y; } 54 inline double dis(Vector a) { return sqrt(Dot(a,a)); } 55 Point p[MAXN]; 56 pii q[MAXN]; 57 int mp[MAXN],m,n; 58 vector<Point>T[MAXN<<2]; 59 ll ans[MAXN]; 60 Point ch[MAXN]; 61 int ty[MAXN]; 62 void Insert(int L,int R,Point pp,int l,int r,int rt){ 63 int mid=l+r>>1; 64 // cout<<L<<" "<<R<<" "<<l<<" "<<r<<" "<<rt<<endl; 65 if(L<=l && r<=R) {T[rt].pb(pp);return ;} 66 // if(l==r) return ; 67 if(R<=mid) Insert(L,R,pp,lson); 68 else if(L>mid) Insert(L,R,pp,rson); 69 else Insert(L,mid,pp,lson),Insert(mid+1,R,pp,rson); 70 } 71 ll Query(int x,int now){ 72 int l=0,r=m-1; 73 while(l<r-2){ 74 int lmid=(l+l+r)/3; 75 int rmid=(l+r+r+2)/3; 76 if(x*ch[lmid].x+ch[lmid].y<x*ch[rmid].x+ch[rmid].y) l=lmid; 77 else r=rmid; 78 } 79 For(i,l,r) ans[now]=max(ans[now],x*ch[i].x+ch[i].y); 80 } 81 void Down(int l,int r,int rt){ 82 int mid=l+r>>1; 83 if(l<r){ 84 Down(lson); 85 Down(rson); 86 } 87 m=0; 88 for(int i=0;i<T[rt].sz;i++){ 89 while(m>1 && Cross(T[rt][i]-ch[m-2],ch[m-1]-ch[m-2])<=0) m--; 90 ch[m++]=T[rt][i]; 91 } 92 For(i,l,r){ 93 if(ty[i]==3) Query(mp[i],i); 94 } 95 } 96 void solve(){ 97 cin>>n; 98 met(mp,0); 99 fill(ans,ans+MAXN,-inf); 100 For(i,0,n*4) T[i].clear(); 101 met(p,0); 102 int ct=0,pt=0,now=0; 103 For(i,1,n){ 104 scanf("%d",&ty[i]); 105 if(ty[i]==1) p[pt].read(),p[pt].l=i,p[pt].r=n,mp[i]=pt++,now++; 106 if(ty[i]==2) {scanf("%d",&m);p[mp[m]].r=i,now--;} 107 if(ty[i]==3) {scanf("%d",&mp[i]);if(now==0) ty[i]=4;} 108 } 109 sort(p,p+pt); 110 For(i,0,pt-1) Insert(p[i].l,p[i].r,p[i],1,n,1); 111 Down(1,n,1); 112 for(int i=1;i<=n;i++){ 113 if(ty[i]==4) puts("EMPTY SET"); 114 if(ty[i]==3) printf("%lld\n",ans[i]); 115 } 116 } 117 int main(){ 118 // fre("in.txt","r",stdin); 119 int t=1; 120 while(t--)solve(); 121 return 0; 122 }
View Code

[CodeForces - 678F] Lena and Queries 線段樹維護凸包