2683: 简单题
Time Limit: 50 Sec Memory Limit: 128 MBSubmit: 1798 Solved: 729
[Submit][Status][Discuss]
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。
接下来每行一个操作。
Output
对于每个2操作,输出一个对应的答案。
Sample Input
4
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
1 2 3 3
2 1 1 3 3
1 2 2 2
2 2 2 3 4
3
Sample Output
3
5
5
HINT
1<=N<=500000,操作数不超过200000个,内存限制20M。
对于100%的数据,操作1中的A不超过2000。
Source
裸的CDQ分治
1 #include <bits/stdc++.h> 2 #define inf 10000000 3 #define ll long long 4 using namespace std; 5 inline int read(){ 6 int x=0;int f=1;char ch=getchar(); 7 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 8 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 9 return x*f; 10 } 11 const int MAXN=1e6+10; 12 struct node{ 13 int x1,y1,x2,y2; 14 int x,y,v; 15 int op,id; 16 }a[MAXN],b[MAXN],d[MAXN]; 17 int ans[MAXN],c[MAXN],n,m; 18 inline int lowbit(int x) {return x&-x;} 19 inline void add(int x,int vv){ 20 while(x<=MAXN){ 21 c[x]+=vv; 22 x+=lowbit(x); 23 } 24 } 25 inline int get(int x){ 26 int ans=0; 27 while(x){ 28 ans+=c[x]; 29 x-=lowbit(x); 30 } 31 return ans; 32 } 33 inline bool cmp1(node n,node m){ 34 return n.x1<m.x1; 35 } 36 inline bool cmp2(node n,node m){ 37 return n.x2<m.x2; 38 } 39 inline bool cmp3(node n,node m){ 40 return n.x<m.x; 41 } 42 void CDQ(int l,int r){ 43 if(l!=r){ 44 int mid=(r+l)>>1; 45 CDQ(l,mid);CDQ(mid+1,r); 46 int p=0; 47 for(int i=l;i<=mid;i++){ 48 if(a[i].op==1){ 49 b[++p]=a[i]; 50 } 51 } 52 sort(b+1,b+p+1,cmp3); 53 int p1=0; 54 for(int i=mid+1;i<=r;i++){ 55 if(a[i].op==2){ 56 d[++p1]=a[i]; 57 } 58 } 59 sort(d+1,d+p1+1,cmp1); 60 int i1=1,i2=1; 61 while(i1<=p&&i2<=p1){ 62 if(b[i1].x<=d[i2].x1-1){ 63 add(b[i1].y,b[i1].v); 64 i1++; 65 } 66 else{ 67 ans[d[i2].id]-=get(d[i2].y2)-get(d[i2].y1-1); 68 i2++; 69 } 70 } 71 for(int i=i2;i<=p1;i++){ 72 ans[d[i].id]-=get(d[i].y2)-get(d[i].y1-1); 73 } 74 for(int i=1;i<=i1-1;i++){ 75 add(b[i].y,-b[i].v); 76 } 77 sort(d+1,d+p1+1,cmp2); 78 i1=1,i2=1; 79 while(i1<=p&&i2<=p1){ 80 if(b[i1].x<=d[i2].x2){ 81 add(b[i1].y,b[i1].v); 82 i1++; 83 } 84 else{ 85 ans[d[i2].id]+=get(d[i2].y2)-get(d[i2].y1-1); 86 i2++; 87 } 88 } 89 for(int i=i2;i<=p1;i++){ 90 ans[d[i].id]+=get(d[i].y2)-get(d[i].y1-1); 91 } 92 for(int i=1;i<=i1-1;i++){ 93 add(b[i].y,-b[i].v); 94 } 95 } 96 } 97 int main(){ 98 n=read(); 99 a[++m].op=read(); 100 while(a[m].op!=3){ 101 a[m].id=m; 102 if(a[m].op==1) a[m].x=read(),a[m].y=read(),a[m].v=read(); 103 else a[m].x1=read(),a[m].y1=read(),a[m].x2=read(),a[m].y2=read(); 104 a[++m].op=read(); 105 } 106 CDQ(1,m-1); 107 for(int i=1;i<=m;i++){ 108 if(a[i].op==2) printf("%d\n",ans[i]); 109 } 110 return 0; 111 }