您的位置:首页 > 其它

POJ2155

2016-04-24 20:34 337 查看
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,
4000
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: