 /**//*
題意:給出一個矩陣,有翻轉操作,還有查詢某個點的值
普通的樹狀數組是修改點,然后查詢區間的,這里與之相反

考慮一維的,用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]記錄的是整個區間的共同修改值?。?br> 所以只要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;
}
|