题目大意
给定一个N*N的网格,刚开始每个网格的值都是0,接下来会对这些网格进行操作,有一下两种操作:
1、”X Y A“对网格C[x][y]增加A
2、”L B R T“ 查询所有(L<=X<=R,B<=Y<=T)的网格],并返回它们的总和
如果是针对于单点修改,那是比区间修改好打很多,因为这个只需要将区间拆分成许多个树状数组就可以了,
然后修改的时候将树状数组修改,十分好理解的。
查询的话就是二维前缀和的查询,然后就可以了。
1 #include<cstdio> 2 #include<algorithm> 3 #include<iostream> 4 #include<cstring> 5 #include<cmath> 6 #define N 1057 7 using namespace std; 8 9 int n,k; 10 int a[N][N]; 11 12 int lowbit(int x) 13 { 14 return x&(-x); 15 } 16 void add(int x,int y,int z) 17 { 18 for (int i=x;i<=n;i+=lowbit(i)) 19 for (int j=y;j<=n;j+=lowbit(j)) 20 a[i][j]+=z; 21 } 22 int query(int x,int y) 23 { 24 int res=0; 25 for (int i=x;i>=1;i-=lowbit(i)) 26 for (int j=y;j>=1;j-=lowbit(j)) 27 res+=a[i][j]; 28 return res; 29 } 30 int main() 31 { 32 while(scanf("%d",&k)) 33 { 34 if (k==0) 35 { 36 scanf("%d",&n); 37 for (int i=1;i<=n;i++) 38 for (int j=1;j<=n;j++) 39 a[i][j]=0; 40 } 41 if (k==1) 42 { 43 int x,y,z; 44 scanf("%d%d%d",&x,&y,&z); 45 x++,y++; 46 add(x,y,z); 47 } 48 if (k==2) 49 { 50 int x1,x2,y1,y2; 51 scanf("%d%d%d%d",&x1,&y1,&x2,&y2); 52 x1++,x2++,y1++,y2++; 53 cout<<query(x2,y2)+query(x1-1,y1-1)-query(x1-1,y2)-query(x2,y1-1)<<endl; 54 } 55 if (k==3) break; 56 } 57 }