 /**//*
題意:給出一個(gè)矩陣,有翻轉(zhuǎn)操作,還有查詢(xún)某個(gè)點(diǎn)的值
普通的樹(shù)狀數(shù)組是修改點(diǎn),然后查詢(xún)區(qū)間的,這里與之相反

考慮一維的,用c[p]記錄整個(gè)區(qū)間(p-2^k,p]被修改的值
所以修改某個(gè)區(qū)間[a,b]操作就可以為 update(b,x),update(a-1,-x)了
update(a,x)是使區(qū)間[1,a]增加x
while(x>0)x-=lowbit(x) [1,a]的更新等價(jià)于拆成很多段去更新
然后對(duì)于查詢(xún)點(diǎn)x操作,考慮與x相關(guān)的區(qū)間即可,即
while(x<=n)x+=lowbit(x)
網(wǎng)上也有,update(a,x)是使區(qū)間[a,N]增加x
然后查詢(xún)那里就是while(x>0)x-=lowbit(x) (因?yàn)楸贿@些區(qū)間影響到)
這樣跟平常的樹(shù)狀數(shù)組寫(xiě)法一樣
不過(guò)我覺(jué)得上面一種比較好理解吧

總之,c[p]記錄的是整個(gè)區(qū)間的共同修改值!!
所以只要c[]數(shù)組正確維護(hù)好了,就容易解決了!!
*/
#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;
}
|