Description
你有一个N*N的棋盘,每个格子内有一个整数,初始时的时候全部为0,现在需要维护两种操作:
命令 |
参数限制 |
内容 |
1 x y A |
1<=x,y<=N,A是正整数 |
将格子x,y里的数字加上A |
2 x1 y1 x2 y2 |
1<=x1<= x2<=N 1<=y1<= y2<=N |
输出x1 y1 x2 y2这个矩形内的数字和 |
3 |
无 |
终止程序 |
Input
输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。
Output
对于每个2操作,输出一个对应的答案。
k-d树维护插入和查询,每插入一定次数重构整棵树
#include<cstdio> #include<algorithm> int X[2],A,la=0; int mns[2],mxs[2],x0,x1,y0,y1; inline void mins(int&x,int y){if(x>y)x=y;} inline void maxs(int&x,int y){if(x<y)x=y;} int read(){ int x=0,c=getchar(); while(c<'0'||c>'9')c=getchar(); while(c>='0'&&c<='9')x=x*10+c-'0',c=getchar(); return x; } struct node{ int m[2]; int mn[2],mx[2]; int v,s,c[2]; void set(){ for(int i=0;i<2;i++)m[i]=mn[i]=mx[i]=X[i]; v=s=A; c[0]=c[1]=0; } }; struct pos{ int x,y,v; }; int d_x=0; bool operator<(pos a,pos b){ if(d_x)return a.y<b.y; else return a.x<b.x; } int op; node ns[200005]; pos ps[200005]; int np=1,pp=0; void upd(int ww){ node&w=ns[ww]; w.s=w.v; for(int i=0;i<2;i++){ if(w.c[i]){ node&u=ns[w.c[i]]; w.s+=u.s; for(int j=0;j<2;j++) mins(w.mn[j],u.mn[j]), maxs(w.mx[j],u.mx[j]); } } } void insert(int ww,int dx){ node&w=ns[ww]; bool f=X[dx]<w.m[dx]; if(w.c[f])insert(w.c[f],dx^1); else w.c[f]=np++; upd(ww); } void ins(){ if(np>1)insert(1,0); else np++; } int build(int l,int r,int d){ d_x=d; int m=l+r>>1; std::nth_element(ps+l,ps+m,ps+r); int ww=np++; node&w=ns[ww]; X[0]=ps[m].x,X[1]=ps[m].y,A=ps[m].v; w.set(); if(l<m)w.c[0]=build(l,m,d^1); else w.c[0]=0; if(m+1<r)w.c[1]=build(m+1,r,d^1); else w.c[1]=0; upd(ww); return ww; } void rebuild(){ np=1; build(0,pp,0); } int ask(int ww=1){ if(!ww)return 0; node&w=ns[ww]; if(x0<=w.mn[0]&&w.mx[0]<=x1&&y0<=w.mn[1]&&w.mx[1]<=y1)return w.s; if(x0>w.mx[0]||x1<w.mn[0]||y0>w.mx[1]||y1<w.mn[1])return 0; int a=0; if(x0<=w.m[0]&&w.m[0]<=x1&&y0<=w.m[1]&&w.m[1]<=y1)a=w.v; for(int i=0;i<2;i++)a+=ask(w.c[i]); return a; } int t=0; int main(){ read(); while(1){ op=read(); if(op==3)break; if(op==1){ ps[pp].x=X[0]=read()^la; ps[pp].y=X[1]=read()^la; ps[pp++].v=A=read()^la; ns[np].set(); ins(); t++; if(t>10000)rebuild(),t=0; }else{ x0=mns[0]=read()^la; y0=mns[1]=read()^la; x1=mxs[0]=read()^la; y1=mxs[1]=read()^la; printf("%d\n",la=ask()); } } return 0; }