[SDOI2014] Vector Set
Title Description
Input and output formats
Input Format
Output Format
Sample input and output
Input Sample # 1
6 A
A 3 2
Q 1 5 1 1
A 15 14
A 12 9
Q 12 8 12 15
Q 21 18 19 18
Sample Output # 1
13
17
17
Explanation
[Title meaning]
Maintenance vector sequence, the sequence is added at the end of support vectors, vector and ask a maximum interval of the dot product of a given vector.
[Official explanations]
[Personal solution to a problem] (the Internet patchwork)
Set the current general inquiry $ y_0> 0 $, then $ \ dfrac {ans} {y_0} = \ max \ {\ dfrac {x_0} {y_0} \ cdot x + y \} $, then the slope of this thing and optimization It looks like the answer must be in the convex hull.
So we maintain this convex hull. Because there are so ask segment tree maintenance interval for each interval of the convex hull. Specifically, when inserted into the current statistical interval has how many points, if the number of points equal to the current length of the interval then construct the convex section shell. inquiry when split into $ \ $ log intervals were run half / third can.
As used herein, the seeking convex hull algorithms sorted by $ $ X coordinate. Note that if a few points $ X $ $ Y $ Yaoan then the same sort.
When each interval is inserted only be constructed once the convex hull, the total complexity of $ O (n \ log n) $, for sorting merge.
When the query is split into $ \ $ log intervals, each interval $ O (\ log n) $-third / two, and the total complexity of $ O (n \ log ^ 2 n) $
Each section must construct a convex hull, so to deal with: Each segment tree node to put a pointer, to open up space to create dynamic convex hull.
Many online discussion codes to merge into a case, only the convex hull maintenance. Safe, and in order that they can better understand, I discuss classification, while maintaining the upper and lower convex hull.
#include<cstdio> #include<algorithm> using namespace std; typedef long long ll; inline void read(int &x){ register char ch=getchar();x=0;register bool f=0; for(;ch<'0'||ch>'9';ch=getchar()) if(ch=='-') f=1; for(;ch>='0'&&ch<='9';ch=getchar()) x=x*10+ch-'0'; if(f) x=-x; } const int N=4e5+3; int n,m,cnt;ll ans;char type[3],op[3]; struct Q{ int opt,l,r,x,y; Q(){} Q(int opt,int l,int r,int x,int y):opt(opt),l(l),r(r),x(x),y(y){} }q[N]; struct point{ int x,y; point(int x=0,int y=0):x(x),y(y){} point operator +(const point &a)const{ return point(x+a.x,y+a.y); } point operator -(const point &a)const{ return point(x-a.x,y-a.y); } ll operator *(const point &a)const{ return (ll)x*a.x+(ll)y*a.y; } ll operator ^(const point &a){ return (ll)x*a.y-(ll)y*a.x; } bool operator <(const point &a)const{ return x==a.x?y<a.y:x<a.x; } }p[N],tmp[N];int tmpsize; struct CH{ point *up,*dw; int upsize,dwsize; void init(int l,int r){ up=new point[r-l+2]; dw=new point[r-l+2]; tmpsize=upsize=dwsize=0; for(int i=l;i<=r;i++) tmp[++tmpsize]=p[i]; sort(tmp+1,tmp+tmpsize+1); for(int i=1;i<=tmpsize;i++){ for(;upsize>1&&((tmp[i]-up[upsize])^(up[upsize]-up[upsize-1]))<=0;upsize--); up[++upsize]=tmp[i]; for(;dwsize>1&&((dw[dwsize]-dw[dwsize-1])^(tmp[i]-dw[dwsize]))<=0;dwsize--); dw[++dwsize]=tmp[i]; } } ll qmax(point p){ int l,r,mid1,mid2;ll res=-(1LL<<62); if(p.y>=0){ l=1;r=upsize; while(r-l>2){ mid1=l+(r-l)/3; mid2=r-(r-l)/3; if(up[mid1]*p<up[mid2]*p) l=mid1; else r=mid2; } for(int i=l;i<=r;i++) res=max(res,up[i]*p); } else{ l=1;r=dwsize; while(r-l>2){ mid1=l+(r-l)/3; mid2=r-(r-l)/3; if(dw[mid1]*p<dw[mid2]*p) l=mid1; else r=mid2; } for(int i=l;i<=r;i++) res=max(res,dw[i]*p); } return res; } }b[N<<2];bool tag[N<<2]; #define lch k<<1 #define rch k<<1|1 ll query(int k,int l,int r,int x,int y,point p){ if(l==x&&r==y){ if(!tag[k]) tag[k]=1,b[k].init(l,r); return b[k].qmax(p); } int mid=l+r>>1; if(y<=mid) return query(lch,l,mid,x,y,p); else if(x>mid) return query(rch,mid+1,r,x,y,p); else return max(query(lch,l,mid,x,mid,p),query(rch,mid+1,r,mid+1,y,p)); } inline void decode(int &x){ if(type[0]=='E') return ; x=x^(ans&0x7fffffff); } int main(){ read(m);scanf("%s",type); for(int i=1,opt,x,y,l,r;i<=m;i++){ scanf("%s",op);opt=(op[0]=='Q'); if(opt){ read(x);read(y); read(l);read(r); } else{ read(x);read(y);l=r=0; ++n; } q[i]=Q(opt,l,r,x,y); } for(int i=1,l,r,x,y;i<=m;i++){ if(q[i].opt){ l=q[i].l;r=q[i].r; x=q[i].x;y=q[i].y; decode(l);decode(r); decode(x);decode(y); ans=query(1,1,n,l,r,point(x,y)); printf("%lld\n",ans); } else{ x=q[i].x;y=q[i].y; decode(x);decode(y); p[++cnt]=point(x,y); } } return 0; }
reward:
All the form $ f [i] = \ min \ limits_ {L (i) \ leq j \ leq R (i)} \ {k (i) x (j) + F (j) \} + G (i) $ of $ dp $ is to do the (slope optimized dynamic programming)