POJ2155

Problem: Matrix
Description: 给你一个矩阵,矩阵中的元素初始化为零。现在对某一区域进行置反操作,然后输出某一个点是零还是一。
Solution: 二维树状数组。这个要用到一个小技巧,我们看看一维的情况,对区间[x,y]中的数进行置反操作,我们可以把点x的值加1,点y的值加1。这样我们要求某一个点的具体值可以对[1,X]这个区间进行求和然后模2。为什么可以这样呢,你可以具体想想,假设我们要求的点在区间[x,y]的左边,那么对求和没有影响;要求的点在区间的中间,那么求和的时候会加上点x的值,这样会改变求和的结果,也会反映点X的情况;要求的点在区间的右边,那么求和的结果会加2,模2了之后对结果没有影响。刚刚讲了一维,那么二维以此类推就好了。
Code(C++):

#include <stdio.h>
#include <string.h>

#define lowbit(x) ((x)&(-x))

const int M=1000+5;

int c[M][M];
int n;

void update(int x,int y,int v)
{
    for(int i=x;i<=n;i+=lowbit(i))
        for(int j=y;j<=n;j+=lowbit(j))
            c[i][j]+=v;
}

int get_sum(int x,int y)
{
    int sum=0;
    for(int i=x;i>=1;i-=lowbit(i))
        for(int j=y;j>=1;j-=lowbit(j))
            sum+=c[i][j];
    return sum;
}

int main()
{
    int N;
    for(scanf("%d",&N);N--;){
        memset(c,0,sizeof(c));
        char tmp[5];
        int T;
        for(scanf("%d%d",&n,&T);T--;){
            scanf("%s",tmp);
            int x1,y1,x2,y2;
            if(tmp[0]=='C'){
                scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
                update(x2+1,y2+1,1);
                update(x1,y1,1);
                update(x2+1,y1,1);
                update(x1,y2+1,1);
            }else
                scanf("%d%d",&x1,&y1),
                printf("%d\n",get_sum(x1,y1)&1);
        }
        puts("");
    }
    return 0;
}

你可能感兴趣的:(poj,Matrix)