二维树状数组,区间更新,单点查询。。
树状数组中的
两个函数 Update()修改某个点的值(准确说是某个路径, 递增或递 减),Getsum()
求和区间(1, x)内的点的值。
修改某点 x 和求和某个区间(1, x)是可以互相调
换的,即我们可以用 Getsum(x, c)修改(1, x)这个区间内的点的值,而用
Update(x)来求该点的值。
我们要使区间(a, b)内的点 + c,只需要使区间(1, b)
内的点+c,而区间(1, a-1)内的点-c 即可。如果是二维的,修改矩阵(x1, y1)
到(x2, y2),即(x2, y2)+c, (x1-1,y2)-c, (x2, y1-1)-c, (x1-1,y1-1)+c 即
可。
#include<cstdio>
#include<cstring>
#define MAXN 1005
#define for if(0);else for
int c[MAXN][MAXN];
int N;
int lowbit(int x){
return x&(-x);
}
void update(int i,int j,int v){
for(int x=i;x<=N;x+=lowbit(x)){
for(int y=j;y<=N;y+=lowbit(y)){
c[x][y]+=v;
}
}
}
int getsum(int i,int j){
int sum=0;
for(int x=i;x>0;x-=lowbit(x)){
for(int y=j;y>0;y-=lowbit(y)){
sum+=c[x][y];
}
}
return sum;
}
int main(){
int t,m;
int first=1;
scanf("%d",&t);
while(t--){
if(first)first=0;
else puts("");
char cmd;
int x1,y1,x2,y2;
scanf("%d%d",&N,&m);
memset(c,0,sizeof(c));
while(m--){
scanf(" %c",&cmd);
if(cmd=='C'){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(x1,y1,1);
update(x1,y2+1,-1);
update(x2+1,y1,-1);
update(x2+1,y2+1,1);
}
else {
scanf("%d%d",&x1,&y1);
int ans=getsum(x1,y1);
if(ans&1)puts("1");
else puts("0");
}
}
}
}