标签:维护 tor pac def 区间 而不是 div title 16px
首先,答案在凸包上为啥?去问ypl
然后点积结果是单峰的所以我们可以用三分查找(为了三分方便,我们要分别维护上下凸壳而不是极角序凸包)
查询区间,所以用线段树维护
动态维护要用高端数据结构,不方便三分,所以我们可以稍微延迟一点
具体点:因为此题的查询有特殊性质,即右端点不会大于当前已加入的数量,所以每当当前加入点到达了某些线段树节点的区间右端点才把整个区间的凸包建好(这样建凸包可以用数组存,方便三分)
#include<stdio.h> #include<algorithm> #include<vector> using namespace std; typedef long long ll; struct point{ int x,y; point(int a=0,int b=0){ x=a; y=b; } }p[400010],stack[400010]; ll operator*(point&a,point&b){ return a.x*(ll)b.x+a.y*(ll)b.y; } ll operator/(point a,point b){ return a.x*(ll)b.y-a.y*(ll)b.x; } point operator-(point&a,point&b){ return point(a.x-b.x,a.y-b.y); } typedef vector<point> vp; vp up[1600010],down[1600010]; ll lastans; int l[400010],r[400010],top; bool op[400010]; void decode(int&x){ x^=lastans&0x7fffffff; } bool cmp1(point a,point b){ if(a.x==b.x)return a.y<b.y; return a.x<b.x; } void getup(vp&v){ if(v.size()==0)return; sort(v.begin(),v.end(),cmp1); top=1; stack[0]=v[0]; int i; for(i=1;i<v.size();i++){ while(top>1&&(stack[top-1]-stack[top-2])/(v[i]-stack[top-1])>=0)top--; stack[top]=v[i]; top++; } v.clear(); for(i=0;i<top;i++)v.push_back(stack[i]); } bool cmp2(point a,point b){ if(a.x==b.x)return a.y>b.y; return a.x<b.x; } void getdown(vp&v){ if(v.size()==0)return; sort(v.begin(),v.end(),cmp2); top=1; stack[0]=v[0]; int i; for(i=1;i<v.size();i++){ while(top>1&&(stack[top-1]-stack[top-2])/(v[i]-stack[top-1])<=0)top--; stack[top]=v[i]; top++; } v.clear(); for(i=0;i<top;i++)v.push_back(stack[i]); } void modify(int pos,point&p,int l,int r,int x){ up[x].push_back(p); down[x].push_back(p); if(pos==r){ getup(up[x]); getdown(down[x]); } if(l==r)return; int mid=(l+r)>>1; if(pos<=mid) modify(pos,p,l,mid,x<<1); else modify(pos,p,mid+1,r,x<<1|1); } ll solve(int x,point&p){ int i,l,r,m1,m2; ll ans=-9223372036854775807ll; if(p.y>0){ l=0; r=up[x].size()-1; while(r-l>2){ m1=((l<<1)+r)/3; m2=(l+(r<<1))/3; if(up[x][m1]*p<up[x][m2]*p) l=m1; else r=m2; } for(i=l;i<=r;i++)ans=max(ans,up[x][i]*p); }else{ l=0; r=down[x].size()-1; while(r-l>2){ m1=((l<<1)+r)/3; m2=(l+(r<<1))/3; if(down[x][m1]*p<down[x][m2]*p) l=m1; else r=m2; } for(i=l;i<=r;i++)ans=max(ans,down[x][i]*p); } return ans; } ll query(int L,int R,point&p,int l,int r,int x){ if(L<=l&&r<=R)return solve(x,p); int mid=(l+r)>>1; ll ans=-9223372036854775807ll; if(L<=mid)ans=max(ans,query(L,R,p,l,mid,x<<1)); if(mid<R)ans=max(ans,query(L,R,p,mid+1,r,x<<1|1)); return ans; } int main(){ int n,m,i,now; char s[5]; bool sec=0; scanf("%d%s",&m,s); if(s[0]!=‘E‘)sec=1; n=0; for(i=1;i<=m;i++){ scanf("%s%d%d",s,&p[i].x,&p[i].y); op[i]=s[0]==‘A‘; if(op[i]) n++; else scanf("%d%d",l+i,r+i); } now=0; for(i=1;i<=m;i++){ if(sec){ decode(p[i].x); decode(p[i].y); } if(op[i]){ now++; modify(now,p[i],1,n,1); }else{ if(sec){ decode(l[i]); decode(r[i]); } printf("%lld\n",lastans=query(l[i],r[i],p[i],1,n,1)); } } }
标签:维护 tor pac def 区间 而不是 div title 16px
原文地址:http://www.cnblogs.com/jefflyy/p/8000464.html