题意:要求支持三个操作,加入删除一个向量,询问当前向量与给定向量的最大值。

题解:线段树时间分治,每个区间做一个凸包,查询的时候到对应区间的凸包上三分。

(话说我这个可能有点问题,三分那一块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 }