你有一个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
|
无
|
终止程序
|
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
1 /*by SilverN*/
2 #include<iostream>
3 #include<algorithm>
4 #include<cstring>
5 #include<cstdio>
6 #include<cmath>
7 using namespace std;
8 const int mxn=200010;
9 int read(){
10 int x=0,f=1;char ch=getchar();
11 while(ch<‘0‘ || ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
12 while(ch>=‘0‘ && ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
13 return x*f;
14 }
15 int n;
16 struct opt{
17 int flag;
18 int x,y,w;
19 int t;
20 int id;
21 }a[mxn*10],b[mxn*10];
22 int cnt=0;
23 int cmp(opt q,opt e){
24 if(q.x==e.x){
25 if(q.y==e.y)return q.flag<e.flag;
26 return q.y<e.y;
27 }
28 return q.x<e.x;
29 }
30 int ans[mxn];
31 int t[mxn*5];
32 void add(int x,int v){while(x<=n){t[x]+=v;x+=x&-x;}return;}
33 int sum(int x){
34 int res=0;
35 while(x){res+=t[x];x-=x&-x;}
36 return res;
37 }
38 void solve(int l,int r){
39 if(l>=r)return;
40 int i,j,mid=(l+r)>>1;
41 int l1=l,l2=mid+1;
42 for(i=l;i<=r;i++){
43 if(a[i].flag==1 && a[i].t<=mid) add(a[i].y,a[i].w);
44 else if(a[i].flag==2 && a[i].t>mid) ans[a[i].id]+=sum(a[i].y)*a[i].w;
45 }
46 for(i=l;i<=r;i++)
47 if(a[i].flag==1 && a[i].t<=mid) add(a[i].y,-a[i].w);
48 for(i=l;i<=r;i++)
49 if(a[i].t<=mid)b[l1++]=a[i];
50 else b[l2++]=a[i];
51 for(i=l;i<=r;i++)a[i]=b[i];
52 solve(l,mid);solve(mid+1,r);
53 return;
54 }
55 int main(){
56 n=read();
57 int i,j,x,y,c,v;
58 int id=0;
59 while(1){
60 c=read();
61 if(c==3)break;
62 if(c==1){//修改
63 x=read();y=read();v=read();
64 a[++cnt].flag=1;a[cnt].x=x;a[cnt].y=y;a[cnt].w=v;
65 a[cnt].t=cnt;
66 }
67 else{//查询
68 x=read();y=read();c=read();v=read();
69 a[++cnt].flag=2;a[cnt].x=x-1;a[cnt].y=y-1;
70 a[cnt].w=1;a[cnt].t=cnt;a[cnt].id=++id;
71 a[++cnt].flag=2;a[cnt].x=x-1;a[cnt].y=v;
72 a[cnt].w=-1;a[cnt].t=cnt;a[cnt].id=id;
73 a[++cnt].flag=2;a[cnt].x=c;a[cnt].y=y-1;
74 a[cnt].w=-1;a[cnt].t=cnt;a[cnt].id=id;
75 a[++cnt].flag=2;a[cnt].x=c;a[cnt].y=v;
76 a[cnt].w=1;a[cnt].t=cnt;a[cnt].id=id;
77 }
78 }
79 sort(a+1,a+cnt+1,cmp);
80 solve(1,cnt);
81 for(i=1;i<=id;i++){
82 printf("%d\n",ans[i]);
83 }
84 return 0;
85 }