//仍然没看懂3109,欸。。
题目描述:给出T组数据,每组数据包括n(一个n*n的初始值为0的矩形)与Questions(表示问题的数目),
每个问题可以有两个操作:
C x1,y1,x2,y2:将[x1,y1]到[x2,y2]的子矩阵中的元素进行not操作。
Q x,y:输出[x,y]的值。
题解:
题目要求二维——poj真难为人,一维还没弄清楚,就直接上二维。。而且在这个问题上《挑战程序设计竞赛》一书就做的不够好,在一维中用了两个辅助树状数组,码农场的hankcs则套用模板,显然不够好。
我们先简化问题:
假设有一个序列,n个数。操作相同,只是变成一维的而已。
我们可以维护一个树状数组sum=a[1]+a[2]....+a[i](a表示当前数据not的次数),
对于修改区间[l,r),则可以很巧妙的add(l,x),add(r,-x),一加一减,r以后的则消去了。
//如果读者对此有所疑惑,可见详解
这样就可以很简洁的扩展到二维了,此问题也就巧妙的解决了。
参考程序:
#include<cstdio>
#include<algorithm>
#include<cstring>
#define maxn 1100
using namespace std;
struct Bit{
int a[maxn][maxn];
int n;
void init(int n){
this->n=n;
memset(a,0,sizeof(a));
}
int bit(int x){
return x & (-x);
}
void add(int x,int y,int data){
while (x<=n){
int ty=y;
while (ty<=n){
a[x][ty]+=data;
ty+=bit(ty);
}
x+=bit(x);
}
}
int query(int x,int y){
int sum=0;
while (x){
int ty=y;
while (ty){
sum+=a[x][ty];
ty-=bit(ty);
}
x-=bit(x);
}
return sum;
}
}map;
int main(){
int T;
scanf("%d",&T);
while (T--){
int n,m;
scanf("%d%d",&n,&m);
map.init(n);
for (int sth=0;sth<m;sth++){
char cmd;
scanf("\n%c",&cmd);
if (cmd=='C'){
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
map.add(x1,y1,1);
map.add(x1,y2+1,1);
map.add(x2+1,y1,1);
map.add(x2+1,y2+1,1);
}else{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",map.query(x,y)&1);
}
}
puts("");
}
return 0;
}