POJ2155

来源:互联网 发布:防噪音耳塞 知乎 编辑:程序博客网 时间:2024/05/22 05:09

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;}
0 0