 /**//*
题意:给出一个矩阵,有翻转操作,还有查询某个点的值
普通的树状数组是修改点,然后查询区间的,这里与之相反

考虑一维的,用c[p]记录整个区间(p-2^k,p]被修改的值
所以修改某个区间[a,b]操作就可以为 update(b,x),update(a-1,-x)了
update(a,x)是使区间[1,a]增加x
while(x>0)x-=lowbit(x) [1,a]的更新等价于拆成很多段去更新
然后对于查询点x操作,考虑与x相关的区间即可,即
while(x<=n)x+=lowbit(x)
网上也有,update(a,x)是使区间[a,N]增加x
然后查询那里就是while(x>0)x-=lowbit(x) (因为被这些区间影响到)
这样跟平常的树状数组写法一样
不过我觉得上面一种比较好理解吧

总之,c[p]记录的是整个区间的共同修改值!!
所以只要c[]数组正确维护好了,就容易解决了!!
*/
#include<cstdio>
#include<cstring>

const int MAXN = 1001;

int c[MAXN][MAXN];
int N,Q;

 int lowbit(int x) {return x&(-x);}

void insert(int x,int y)
  {
while(x>0)
 {
int yy = y;
while(yy>0)
 {
c[x][yy]^=1;
yy-=lowbit(yy);
}
x-=lowbit(x);
}
}
int find(int x,int y)
  {
int ans = 0;
while(x<=N)
 {
int yy = y;
while(yy<=N)
 {
ans^=c[x][yy];
yy+=lowbit(yy);
}
x+=lowbit(x);
}
return ans;
}
int main()
  {
int T,t=0;
scanf("%d",&T);
while(T--)
 {
scanf("%d%d",&N,&Q);
memset(c,0,sizeof(c));
char ch[10];
int x1,y1,x2,y2;
while(Q--)
 {
scanf("%s%d%d",&ch,&x1,&y1);
if(ch[0]=='C')
 {
scanf("%d%d",&x2,&y2);
insert(x2,y2);
insert(x1-1,y2);
insert(x2,y1-1);
insert(x1-1,y1-1);
}
else printf("%d\n",find(x1,y1));
}
if(T)puts("");
}
return 0;
}
|