https://vjudge.net/problem/POJ-2155
给定一个矩阵,初始化都为0
两种操作
1 给定区间 左上角和右下角,将区间内坐标(闭区间) 取反操作
2 查询 某单点。
没有想到这样搞,很6,取反的操作、(摘自大佬的照片)
http://blog.csdn.net/zxy_snow/article/details/6264135 这个
每次依据四个点。(注意右下角那个x,y要加1,这样就不会把边界加进去。另外俩也是)
2 为什么判断他们之间的操作,需要求 区间和(1,1-x,y)就可以呢qwq
(摘自《浅谈信息学竞赛中的“0”和“1”》)
http://blog.csdn.net/libin56842/article/details/46620445
当 在6时,计算两次,会抵消。8也是,9是计算4次抵消(和上面那个更新的操作好像,得出的结论就是该点的左上角的任何操作都不会对该点产生影响。该点会出现在 4,6,89,qwq)唯一产生影响的地方就是5,即直接的改变过该点的地方,而这,正好就是我们想要的qwq
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <string>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <math.h>
#include <bitset>
#include <list>
#include <algorithm>
#include <climits>
using namespace std;
#define lowbit(x) (x&-x)
const int mod = 1e9+7;
/* 树状数组 区间求值。求得是 前缀和。
1 开始没有理解他更新的位置。这样操作是为了让边界也只进行
1 次更新,否则的话,边界就会进行4次更新。
2 查询单点也行了,(单点查询是为了干啥)
*/
int m,n;
int bit[1005][1005];
void add(int a,int b){
for(int i=a;i<=m;i+=lowbit(i))
for(int j=b;j<=m;j+=lowbit(j)){
bit[i][j]++;
}//区间修改。
}
int query(int a,int b){
int sum=0;
for(int i=a;i>=1;i-=lowbit(i))
for(int j=b;j>=1;j-=lowbit(j))
sum+=bit[i][j];
return sum;
//区间查询
}
int main()
{ int t;
char s;
scanf("%d",&t);
int a,b,c,d;
while(t--){
memset(bit,0,sizeof(bit));
scanf("%d%d",&m,&n);
for(int i=1;i<=n;i++){
cin>>s;
if(s=='C'){
scanf("%d%d%d%d",&a,&b,&c,&d);
a++,b++,c++,d++;
add(c,d);//右下测区域
add(a-1,b-1);//全部
add(a-1,d);//下侧
add(c,b-1);//右侧
}
else {
scanf("%d%d",&a,&b);
printf("%d\n",query(a,b)%2);
}
}
printf("\n");
}
return 0;
}