题目链接
https://vjudge.net/problem/POJ-2155
题意:
给你一个n*n的正方形,每个位置不是1就是0,初始时都是0. 有两种操作:
C :翻转某个区间。翻转每个位置0变成1,1变成0.
Q: 查询某个位置的值。
题解
如果某个区间翻转一次,我们这个区间每个位置都加1,每个位置用来记录翻转的次数。
那么查询某个位置的时候。如果这个位置翻转了奇数次就输出1,偶数次就输出0.
如果修改一个区间的时候一个一个修改,那么肯定会超时。
那么可以用二维树状数组来做。结合二维差分 ,前缀和的知识。
代码
#include<algorithm>
#include <iostream>
#include<cstring>
#include <cstdio>
using namespace std;
const int maxn=1e3+10;
int bit[maxn][maxn];
int n,m;
void add(int x,int y,int d){
for(int i=x;i<=n;i+=i&-i){
for(int j=y;j<=n;j+=j&-j){
bit[i][j]+=d;
}
}
}
int sum(int x,int y){
int ans=0;
for(int i=x;i;i-=i&-i){
for(int j=y;j;j-=j&-j){
ans+=bit[i][j];
}
}
return ans;
}
int main(){
int t;
cin>>t;
while(t--){
cin>>n>>m;
memset(bit,0,sizeof(bit));
while(m--){
char c[2];
scanf("%s",c);
if(c[0]=='Q'){
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",sum(x,y)%2);
}else{
int x1,x2,y1,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
add(x1,y1,1);
add(x2+1,y1,-1);
add(x1,y2+1,-1);
add(x2+1,y2+1,1);
}
}
if(t) printf("\n");
}
return 0;
}