/**//* 题意:给出一个矩阵,有翻转操作,还有查询某个点的值 普通的树状数组是修改点,然后查询区间的,这里与之相反
考虑一维的,用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; }
|