题意:要求支持三个操作,加入删除一个向量,询问当前向量与给定向量的最大值。
题解:线段树时间分治,每个区间做一个凸包,查询的时候到对应区间的凸包上三分。
(话说我这个可能有点问题,三分那一块R-L>=20我才过的。。)
1 #include<bits/stdc++.h> 2 using namespace std; 3 #define LL long long 4 #define N 300005 5 6 inline LL read(){ 7 LL x=0,f=1; char a=getchar(); 8 while(a<'0' || a>'9') {if(a=='-') f=-1; a=getchar();} 9 while(a>='0' && a<='9') x=x*10+a-'0',a=getchar(); 10 return x*f; 11 } 12 13 int n,cnt,st[N],ed[N],qnum,root,ti[N]; 14 LL ans; 15 16 struct point{ 17 LL x,y; 18 bool operator < (const point& w)const{ 19 if(x==w.x) return y<w.y; 20 return x<w.x; 21 } 22 }p[N],Q[N],tmp[N]; 23 24 point operator - (const point& a,const point& b){return (point){a.x-b.x,a.y-b.y};} 25 26 inline LL cross(point a,point b){return a.x*b.y-a.y*b.x;} 27 28 LL operator * (const point& a,const point& b){ 29 return a.x*b.x+a.y*b.y; 30 } 31 32 struct segment{ 33 int l,r; 34 vector<point>s; 35 }a[4*N]; 36 37 void build(int k,int l,int r){ 38 a[k].l=l; a[k].r=r; 39 if(l==r) return; 40 int mid=(l+r)>>1; 41 build(k<<1,l,mid); build(k<<1|1,mid+1,r); 42 } 43 44 void insert(int k,int L,int R,int x){ 45 int l=a[k].l,r=a[k].r; 46 if(l==L && r==R) {a[k].s.push_back(p[x]); return;} 47 int mid=(l+r)>>1; 48 if(R<=mid) insert(k<<1,L,R,x); 49 else if(mid<L) insert(k<<1|1,L,R,x); 50 else insert(k<<1,L,mid,x),insert(k<<1|1,mid+1,R,x); 51 } 52 53 void convexhull(int k){ 54 if(!a[k].l) return; 55 int len=a[k].s.size(); 56 sort(a[k].s.begin(),a[k].s.end()); 57 int top=0; 58 for(int i=0;i<len;i++){ 59 while(top>1 && cross(a[k].s[i]-tmp[top-1],tmp[top]-tmp[top-1])>=0) top--; 60 tmp[++top]=a[k].s[i]; 61 } 62 int tt=top; 63 for(int i=len-2;i>=0;i--){ 64 while(top>tt && cross(a[k].s[i]-tmp[top-1],tmp[top]-tmp[top-1])>=0) top--; 65 tmp[++top]=a[k].s[i]; 66 } 67 if(len>1) top--; 68 a[k].s.clear(); 69 for(int i=1;i<=top;i++) a[k].s.push_back(tmp[i]); 70 convexhull(k<<1); convexhull(k<<1|1); 71 } 72 73 void query(int k,int pos,int num){ 74 int l=a[k].l,r=a[k].r; 75 int L=0,R=a[k].s.size()-1; 76 while(R-L>=3){ 77 int ll=L+(R-L)/3,rr=R-(R-L)/3; 78 if(Q[num]*a[k].s[ll]>Q[num]*a[k].s[rr]) R=rr; 79 else L=ll; 80 } 81 for(int i=L;i<=R;i++) 82 ans=max(ans,Q[num]*a[k].s[i]); 83 if(l==r) return; 84 int mid=(l+r)>>1; 85 if(pos<=mid) query(k<<1,pos,num); 86 else query(k<<1|1,pos,num); 87 } 88 89 int main(){ 90 n=read(); 91 for(int i=1;i<=n;i++){ 92 int type=read(); 93 if(type==1) p[++cnt].x=read(),p[cnt].y=read(),st[cnt]=i; 94 else if(type==2) ed[read()]=i; 95 else Q[++qnum].x=read(),Q[qnum].y=read(),ti[qnum]=i; 96 } 97 build(1,1,n); 98 for(int i=1;i<=cnt;i++) if(!ed[i]) ed[i]=n; 99 for(int i=1;i<=cnt;i++) insert(1,st[i],ed[i],i); 100 convexhull(1); 101 for(int i=1;i<=qnum;i++) ans=0,query(1,ti[i],i),printf("%lld\n",ans); 102 return 0; 103 }