BZOJ3533: [Sdoi2014]向量集
Posted CHADLZX
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ3533: [Sdoi2014]向量集相关的知识,希望对你有一定的参考价值。
可能是我的实现姿势有问题,常数很大,不过可以卡过去.
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<ctime> #include<cmath> #include<algorithm> #include<queue> #include<set> #include<map> #include<iomanip> using namespace std; #define ll long long #define db double #define up(i,j,n) for(int i=j;i<=n;i++) #define pii pair<int,int> #define uint unsigned int #define FILE "dealing" #define eps 1e-4 int read(){ int x=0,f=1,ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘){x=(x<<1)+(x<<3)+ch-‘0‘;ch=getchar();} return x*f; } template<class T> bool cmax(T& a,T b){return a<b?a=b,true:false;} template<class T> bool cmin(T& a,T b){return a>b?a=b,true:false;} const ll maxn=1600550,limit=50100,inf=(ll)(1e18),mod=(int)1e9+7; int n,cnt=0; int xx[maxn],yy[maxn]; int L=0,root[maxn],Long[maxn],midd[maxn]; int fL=0,froot[maxn],fLong[maxn],fmidd[maxn]; struct vec{ ll x,y; vec(ll x=0,ll y=0):x(x),y(y){} vec operator-(const vec& b){return vec(x-b.x,y-b.y);} bool operator<(const vec& b)const{return x<b.x||(x==b.x&&y<b.y);} }ch[maxn],q[maxn<<2],fq[maxn<<2],que[maxn]; ll cro(vec a,vec b){return a.x*b.y-a.y*b.x;} ll dot(vec a,vec b){return a.x*b.x+a.y*b.y;} void build(int l,int r,int o){ root[o]=++L;int tail=0; up(i,l,r) if(yy[i]>0)ch[++tail]=vec(xx[i],yy[i]); sort(ch+1,ch+tail+1); que[1]=ch[1];int top=1; up(i,2,tail){ while(top>1&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--; que[++top]=ch[i]; } int k=top; for(int i=tail-1;i>=1;i--){ while(top>k&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--; que[++top]=ch[i]; } if(!tail)top=0,k=0; up(i,L,L+top-1)q[i]=que[i-L+1]; midd[o]=k;Long[o]=top; L=L+top-1; froot[o]=++fL;tail=0; up(i,l,r)if(yy[i]<=0)ch[++tail]=vec(xx[i],yy[i]); sort(ch+1,ch+tail+1); que[1]=ch[1];top=1; up(i,2,tail){ while(top>1&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--; que[++top]=ch[i]; } k=top; for(int i=tail-1;i>=1;i--){ while(top>k&&cro(que[top]-que[top-1],ch[i]-que[top-1])<=0)top--; que[++top]=ch[i]; } if(!tail)top=0,k=0; up(i,fL,fL+top-1)fq[i]=que[i-fL+1]; fLong[o]=top;fmidd[o]=k; fL=fL+top-1; } void add(int l,int r,int x,int y,int o){ if(l>cnt||r<cnt)return; if(l==r){ xx[l]=x,yy[l]=y; build(l,r,o); return; } int mid=(l+r)>>1; add(l,mid,x,y,o<<1); add(mid+1,r,x,y,o<<1|1); if(r==cnt)build(l,r,o); } ll Ans=-inf; void divide(int x,int y,int o){ if(root[o]+Long[o]-1<root[o])return; int l=root[o],r=root[o]+midd[o]-1; ll ans=-inf; while(l+3<=r){ int mid1=(l+l+r)/3; ll ans1=(ll)dot(q[mid1],vec(x,y)); int mid2=(l+r+r)/3; ll ans2=(ll)dot(q[mid2],vec(x,y)); if(ans1<=ans2)l=mid1; else r=mid2; } up(i,l,r)cmax(ans,(ll)dot(q[i],vec(x,y))); cmax(Ans,ans); l=root[o]+midd[o]-1,r=root[o]+Long[o]-1; ans=-inf; while(l+3<=r){ int mid1=(l+l+r)/3; ll ans1=(ll)dot(q[mid1],vec(x,y)); int mid2=(l+r+r)/3; ll ans2=(ll)dot(q[mid2],vec(x,y)); if(ans1<=ans2)l=mid1; else r=mid2; } up(i,l,r)cmax(ans,(ll)dot(q[i],vec(x,y))); cmax(Ans,ans); } void divide2(int x,int y,int o){ if(froot[o]+fLong[o]-1<froot[o])return; int l=froot[o],r=froot[o]+fmidd[o]-1; ll ans=-inf; while(l+3<=r){ int mid1=(l+l+r)/3; ll ans1=(ll)dot(fq[mid1],vec(x,y)); int mid2=(l+r+r)/3; ll ans2=(ll)dot(fq[mid2],vec(x,y)); if(ans1<ans2)l=mid1; else r=mid2; } up(i,l,r)cmax(ans,(ll)dot(fq[i],vec(x,y))); cmax(Ans,ans); l=froot[o]+fmidd[o]-1,r=froot[o]+fLong[o]-1; ans=-inf; while(l+3<=r){ int mid1=(l+l+r)/3; ll ans1=(ll)dot(fq[mid1],vec(x,y)); int mid2=(l+r+r)/3; ll ans2=(ll)dot(fq[mid2],vec(x,y)); if(ans1<ans2)l=mid1; else r=mid2; } up(i,l,r)cmax(ans,(ll)dot(fq[i],vec(x,y))); cmax(Ans,ans); } void query(int l,int r,int x,int y,int ql,int qr,int o){ if(l>qr||r<ql)return; if(l>=ql&&r<=qr){ divide(x,y,o); divide2(x,y,o); return; } int mid=(l+r)>>1; query(l,mid,x,y,ql,qr,o<<1); query(mid+1,r,x,y,ql,qr,o<<1|1); } char s; ll last=0; int de(int x){ if(s==‘E‘)return x; return x ^ (last & 0x7fffffff); } int main(){ freopen(FILE".in","r",stdin); freopen(FILE".out","w",stdout); n=read();char ch;scanf(" %c",&s); up(i,1,n){ int x,y,l,r; scanf(" %c",&ch); if(ch==‘A‘){ cnt++; x=de(read()),y=de(read()); add(1,n,x,y,1); } if(ch==‘Q‘){ x=de(read()),y=de(read()),l=de(read()),r=de(read()); Ans=-inf; query(1,n,x,y,l,r,1); printf("%lld\n",last=Ans); } } cout<<clock()<<endl; return 0; }
以上是关于BZOJ3533: [Sdoi2014]向量集的主要内容,如果未能解决你的问题,请参考以下文章