Matrix
题意:给定n*n的矩阵,每次选定一个矩形区域取反,询问[x,y]的值是多少。
思路:树状数组维护,具体看下面的图,容斥原理,图片来源https://blog.csdn.net/libin56842/article/details/46620445
#include<cstdio>
#include<cstring>
int c[1005][1005];
int n;
void up(int x,int y){
for(int i=x;i<=n;i+=i&(-i))
for(int j=y;j<=n;j+=j&(-j))
c[i][j]++;
}
int qu(int x,int y){
int ans=0;
for(int i=x;i>0;i-=i&(-i))
for(int j=y;j>0;j-=j&(-j))
ans+=c[i][j];
return ans;
}
int main(){
int T;
scanf("%d",&T);
while(T--){
int m;
scanf("%d%d",&n,&m);
memset(c,0,sizeof(c));
while(m--){
char s[2];
int x1,x2,y1,y2;
scanf("%s",s);
if(s[0]=='C'){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
up(x1,y1);
up(x1,y2+1);
up(x2+1,y2+1);
up(x2+1,y1);
}
else{
scanf("%d%d",&x1,&y1);
int temp=qu(x1,y1);
printf("%d\n",temp%2);
}
}
printf("\n");
}
}
线段树版本
#include<cstdio>
#include<cstring>
int tr[4005][4005];
int x1,x2,y1,y2,x,y;
int ans,n;
void upy(int ox,int l,int r,int o){
if(y1<=l&&y2>=r){
tr[ox][o]++;
return;
}
int m=(l+r)>>1;
if(m>=y1)
upy(ox,l,m,o*2);
if(y2>m)
upy(ox,m+1,r,o*2+1);
}
void upx(int o,int l,int r){
if(x1<=l&&x2>=r){
upy(o,1,n,1);
return;
}
int m=(l+r)>>1;
if(m>=x1)
upx(o*2,l,m);
if(x2>m)
upx(o*2+1,m+1,r);
}
void quy(int ox,int l,int r,int o){
ans+=tr[ox][o];
if(l==r){
return;
}
int m=(l+r)>>1;
if(m>=y)
quy(ox,l,m,o*2);
if(y>m)
quy(ox,m+1,r,o*2+1);
}
void qux(int o,int l,int r){
quy(o,1,n,1);
if(l==r){
return;
}
int m=(l+r)>>1;
if(m>=x)
qux(o*2,l,m);
if(x>m)
qux(o*2+1,m+1,r);
}
int main(){
int T;
scanf("%d",&T);
while(T--){
memset(tr,0,sizeof(tr));
char c[5];
int m;
scanf("%d%d",&n,&m);
while(m--){
scanf("%s",c);
if(c[0]=='C'){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
upx(1,1,n);
}
else{
ans=0;
scanf("%d%d",&x,&y);
qux(1,1,n);
printf("%d\n",ans%2);
}
}
printf("\n");
}
}