这道题目由于空间为20M因此只能使用k-d tree。由于在线插入可能会导致不平衡,因此需要使用替罪羊树的思想暴力重构,保证时间复杂度。由于k-d tree是查询大于插入的,因此可以把平衡因子设的小一点(代码中的0.7还是不够小)。
AC代码如下:
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cstdlib> #define N 200005 using namespace std; int tot,cnt,rt,sx,sy,tx,ty,dms,ans,h[N]; int read(){ int x=0; char ch=getchar(); while (ch<'0' || ch>'9') ch=getchar(); while (ch>='0' && ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } return x; } void up(int &u,int v){ if (u<v) u=v; } void dn(int &u,int v){ if (u>v) u=v; } struct node{ int d[2],x[2],y[2],ls,rs,sum,val,sz,dc; void pfs(int u,int v,int w){ x[0]=x[1]=d[0]=u; y[0]=y[1]=d[1]=v; sum=val=w; sz=1; } void clr(){ x[0]=x[1]=d[0]; y[0]=y[1]=d[1]; ls=rs=0; sum=val; sz=1; } }p[N]; bool cmp(int x,int y){ return p[x].d[dms]<p[y].d[dms]; } struct kd_tree{ void maintain(int k,int t){ p[k].sum+=p[t].sum; p[k].sz+=p[t].sz; dn(p[k].x[0],p[t].x[0]); up(p[k].x[1],p[t].x[1]); dn(p[k].y[0],p[t].y[0]); up(p[k].y[1],p[t].y[1]); } void del(int k){ h[++cnt]=k; if (p[k].ls) del(p[k].ls); if (p[k].rs) del(p[k].rs); } void build(int &k,int l,int r,int now){ int mid=(l+r)>>1; dms=now; nth_element(h+l,h+mid,h+r+1,cmp); k=h[mid]; p[k].clr(); p[k].dc=now; if (l<mid){ build(p[k].ls,l,mid-1,now^1); maintain(k,p[k].ls); } if (mid<r){ build(p[k].rs,mid+1,r,now^1); maintain(k,p[k].rs); } } void ins(int &k,int np){ if (!k){ k=np; p[k].dc=rand()&1; return; } maintain(k,np); dms=p[k].dc; if (p[np].d[dms]<p[k].d[dms]) if (p[p[k].ls].sz>p[k].sz*0.7){ h[cnt=1]=np; del(k); build(k,1,cnt,dms); } else ins(p[k].ls,np); else if (p[p[k].rs].sz>p[k].sz*0.7){ h[cnt=1]=np; del(k); build(k,1,cnt,dms); } else ins(p[k].rs,np); } bool ok(int k){ return p[k].x[0]<=tx && p[k].x[1]>=sx && p[k].y[0]<=ty && p[k].y[1]>=sy; } void qry(int k){ if (sx<=p[k].x[0] && p[k].x[1]<=tx && sy<=p[k].y[0] && p[k].y[1]<=ty){ ans+=p[k].sum; return; } if (sx<=p[k].d[0] && p[k].d[0]<=tx && sy<=p[k].d[1] && p[k].d[1]<=ty) ans+=p[k].val; if (p[k].ls && ok(p[k].ls)) qry(p[k].ls); if (p[k].rs && ok(p[k].rs)) qry(p[k].rs); } }kd; int main(){ srand(20160414); int cas,x=read()>>1,y; tot=rt=1; p[1].pfs(x,x,0); for (cas=read(); cas!=3; cas=read()) if (cas==1){ x=read()^ans; y=read()^ans; p[++tot].pfs(x,y,read()^ans); kd.ins(rt,tot); } else{ sx=read()^ans; sy=read()^ans; tx=read()^ans; ty=read()^ans; ans=0; kd.qry(rt); printf("%d\n",ans); } return 0; }
by lych
2016.4.14