题目:http://poj.org/problem?id=2155
二维树状数组:
C[1][1]=a11,
C[1][2]=a11+a12,
C[1][3]=a13,
C[1][4]=a11+a12+a13+a14,,,
C[2][1]=a11+a21,
C[2][2]=a11+a12+a21+a22,
C[2][3]=a13+a23,
C[2][4]=a11+a12+a13+a14+a21+a22+a23+a24……
C[3][1]=a31,
C[3][2]=a31+a32,
C[3][3]=a33,
C[3][4]=a31+a32+a33+a34……
C[4][1]=a11+a21+a31+a41,
C[4][2]=a11+a12+a21+a22+a31+a32+a41+a42,
C[4][3]=a13+a23+a33+a43,... …………
再偷一张图:(摘自http://blog.csdn.net/acm_BaiHuzi/article/details/46819049)
二维数组可看成平面举矩形,这道题就好理解多了。
#include<stdio.h>
#include<string.h>
#define maxn 1010
int tree[maxn][maxn];
int lowbit(int i){
return i&(-i);
}
void update(int x,int y,int t){
for(int i=x;i<maxn;i+=lowbit(i)){
for(int j=y;j<maxn;j+=lowbit(j)){
tree[i][j]+=t;
}
}
}
int query(int x,int y){
int sum,i,j;
for(i=x;i>0;i-=lowbit(i))
for(j=y;j>0;j-=lowbit(j))
sum+=tree[i][j];
return sum;
}
main(){
int n,a,b,x,y,x1,x2,y1,y2;
char s[3];
scanf("%d",&n);
while(n--){
scanf("%d%d",&a,&b);
memset(tree,0,sizeof tree);
while(b--){
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(x1,y1,1);
update(x1,y2+1,-1);
update(x2+1,y1,-1);
update(x2+1,y2+1,1);/*加上重复被剪掉的*/
}
if(s[0]=='Q'){
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y)%2);/*巧妙的将0和1转化成操作的个数,操作偶数次则经过偶数次变换仍为0*/
}
}
if(b)
printf("\n");
}
}