你有一个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
|
无
|
终止程序
|
输入文件第一行一个正整数N。
接下来每行一个操作。每条命令除第一个数字之外,
均要异或上一次输出的答案last_ans,初始时last_ans=0。
数据规模和约定
1<=N<=500000,操作数不超过200000个,内存限制20M,保证答案在int范围内并且解码之后数据仍合法。
样例解释见OJ2683
新加数据一组,但未重测----2015.05.24
1 /*by SilverN*/
2 #include<algorithm>
3 #include<iostream>
4 #include<cstring>
5 #include<cstdio>
6 #include<cmath>
7 #include<vector>
8 #define LL long long
9 using namespace std;
10 const int mxn=250010;
11 LL read(){
12 LL x=0,f=1;char ch=getchar();
13 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
14 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
15 return x*f;
16 }
17 struct node{
18 int l,r;
19 int min[2],max[2];
20 int d[2];
21 int w;
22 LL sum;
23 }t[mxn];
24 int root=0,nowD;
25 int cmp(const node a,const node b){
26 return a.d[nowD]<b.d[nowD];
27 }
28 int n,cnt;
29 int lim=0;
30 inline void pushup(int rt,int x){
31 t[rt].max[0]=max(t[rt].max[0],t[x].max[0]);
32 t[rt].max[1]=max(t[rt].max[1],t[x].max[1]);
33 t[rt].min[0]=min(t[rt].min[0],t[x].min[0]);
34 t[rt].min[1]=min(t[rt].min[1],t[x].min[1]);
35 return;
36 }
37 inline bool in(int x1,int y1,int x2,int y2,int k){
38 return (x1<=t[k].min[0] && t[k].max[0]<=x2 &&
39 y1<=t[k].min[1] && t[k].max[1]<=y2);
40 }
41 inline bool out(int x1,int y1,int x2,int y2,int k){
42 return (x1>t[k].max[0] || x2<t[k].min[0] || y1>t[k].max[1] || y2<t[k].min[1]);
43 }
44 int Build(int l,int r,int D){
45 if(l>r)return 0;
46 nowD=D;int mid=(l+r)>>1;
47 nth_element(t+l,t+mid,t+r+1,cmp);///
48 t[mid].max[0]=t[mid].min[0]=t[mid].d[0];
49 t[mid].max[1]=t[mid].min[1]=t[mid].d[1];
50 t[mid].sum=t[mid].w;
51 //
52 t[mid].l=Build(l,mid-1,D^1);
53 if(t[mid].l)pushup(mid,t[mid].l);
54 t[mid].r=Build(mid+1,r,D^1);
55 if(t[mid].r)pushup(mid,t[mid].r);
56 //
57 t[mid].sum=t[mid].w+t[t[mid].l].sum+t[t[mid].r].sum;
58 return mid;
59 }
60 void insert(int &now,int x,int D){
61 if(!now){now=x;return;}
62 if(t[x].d[D]==t[now].d[D] && t[x].d[!D]==t[now].d[!D]){
63 t[now].w+=t[x].w;
64 t[now].sum+=t[x].w;
65 --cnt;
66 return;
67 }
68 if(t[x].d[D]<t[now].d[D]){
69 insert(t[now].l,x,D^1);
70 pushup(now,t[now].l);
71 }
72 else{
73 insert(t[now].r,x,D^1);
74 pushup(now,t[now].r);
75 }
76 t[now].sum=t[now].w+t[t[now].l].sum+t[t[now].r].sum;
77 return;
78 }
79 LL query(int rt,int x1,int y1,int x2,int y2){
80 if(!rt)return 0;
81 LL res=0;
82 if(in(x1,y1,x2,y2,rt)){return t[rt].sum;}
83 if(out(x1,y1,x2,y2,rt)){return 0;}
84 if(x1<=t[rt].d[0] && t[rt].d[0]<=x2 &&
85 y1<=t[rt].d[1] && t[rt].d[1]<=y2) res+=t[rt].w;
86 res+=query(t[rt].l,x1,y1,x2,y2)+query(t[rt].r,x1,y1,x2,y2);
87 return res;
88 }
89 int main(){
90 int i,j,op,x,y,w;
91 n=read();lim=9000;
92 LL lans=0;int X1,X2,Y1,Y2;
93 while(1){
94 op=read();
95 if(op==3)break;
96 if(op==1){
97 t[++cnt].d[0]=read()^lans;t[cnt].d[1]=read()^lans;
98 t[cnt].w=read()^lans;t[cnt].sum=t[cnt].w;
99 t[cnt].max[0]=t[cnt].min[0]=t[cnt].d[0];
100 t[cnt].max[1]=t[cnt].min[1]=t[cnt].d[1];
101 insert(root,cnt,0);
102 if(cnt==lim){
103 lim+=9000;
104 root=Build(1,cnt,0);
105 }
106 }
107 else{
108
109 X1=read()^lans;Y1=read()^lans;X2=read()^lans;Y2=read()^lans;
110 lans=query(root,X1,Y1,X2,Y2);
111 printf("%lld\n",lans);
112 }
113 }
114 return 0;
115 }