题意:
已知n*n 个格子的矩阵。有q次操作 (初始状态全部为0)
c: 给定左上角的点与右下角的点将区间内的点全部反转
q:询问(x,y)点的状态
分析:
不是自己想的方法,通过搜类型题知道这是二维树状数组,所以直接确定了方向
如果对于(x1,y1)-(x2,y2)区间内的点进行反转
可以对图中的四个点用二位树状数组进行反转,偶数次反转就被抵消了。
图片来源:水印上的链接
询问的时候我们只需要当前点被反转了多少次,也就是被更新了多少次。
用树状数组求和进行运算
代码:
#include<cstdio>
#include<cstring>
using namespace std;
#define N 1005
int c[N][N];
int a[N][N];
int T;
int lowb(int x){
return x&(-x);
}
void updata(int u,int v){
while(u<N){
int t=v;
while(t<N){
c[u][t]=!c[u][t];
t+=lowb(t);
}
u+=lowb(u);
}
}
int result(int u,int v){
int res=0;
while(u>0){
int t=v;
while(t>0){
res+=c[u][t];
t-=lowb(t);
}
u-=lowb(u);
}
return res%2;
}
int main(){
scanf("%d",&T);
while(T--){
int n,q,u,v,x,y;
scanf("%d%d",&n,&q);
memset(a,0,sizeof(a));
memset(c,0,sizeof(c));
while(q--){
char op[2];
scanf("%s",op);
if(op[0]=='C'){
scanf("%d%d%d%d",&u,&v,&x,&y);
updata(u,v);
updata(u,y+1);
updata(x+1,v);
updata(x+1,y+1);
}else {
scanf("%d%d",&u,&v);
printf("%d\n",result(u,v));
}
}
if(T)printf("\n");
}
}