POJ 2155 矩阵(二维树状数组 区间更新 单点查找)

题目: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)

POJ 2155 矩阵(二维树状数组 区间更新 单点查找)_第1张图片

二维数组可看成平面举矩形,这道题就好理解多了。

#include
#include

#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;i0;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");
    }
}



你可能感兴趣的:(树状数组)