题意:给你一个区间,面积为n*n,在这个区间里进行操作。首先输入0 n,所以区间里的点的范围为
0<= x < n,0<= y < n,区间范围内每个点的初始手机都为0。分别有三种操作 1 x y z,在点(x,y)上加上z部手机。2 x1 y1 x2 y2 问区间x1<= x <=x2 , y1 <= y <= y2上一共有多少手机。3 结束循环。
。。。这题。。对于二维树状数组不熟悉,区间取错了wa了好几次。。
思路:二维树状数组,因为0 <= x,y < n, 我们把区间移一下好操作,把区间移为 1 <= x,y <= n。再修改区间或者询问区间的时候把x++,y++就可以了,其它就是常规操作。
AC代码:
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
const int maxn = 2000;
int sum[maxn][maxn],n;
int lowbit(int x){
return x&(-x);
}
void add(int x,int y,int z){
for(int i = x; i <= n; i+=lowbit(i)){
for(int j = y; j <= n; j+=lowbit(j))
sum[i][j] += z;
}
}
int query(int x,int y){
int ans = 0;
for(int i = x; i > 0; i-=lowbit(i))
for(int j = y; j > 0; j-=lowbit(j))
ans += sum[i][j];
return ans;
}
int main(){
int c;
while(scanf("%d%d",&c,&n)!=EOF){
memset(sum, 0, sizeof(sum));
while(1){
scanf("%d",&c);
if(c == 1){
int x, y, z;
scanf("%d%d%d",&x,&y,&z);
add(x+1,y+1,z);
}
else if(c == 2){
int x1, y1, x2, y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
printf("%d\n",query(x2+1,y2+1) - query(x1,y2+1) - query(x2+1,y1) + query(x1, y1)); //这里一定要注意区间,之前写错WA了好多次
}
else if(c == 3)
break;
}
}
return 0;
}