学习链接:http://www.java3z.com/cwbwebhome/article/article1/1369.html?id=4804
题意:一个n*n的矩阵,两种操作,更新以A[x1,y1]为左上角,A[x2,y2]为右下角的矩阵,查询A[i,j]点的值
思路:二维树状数组好题,就查询操作而言,只要知道那个点的翻转次数的奇偶性就可以了,所以每次操作我们只需要更新四个点,然后求(1,1)到该点的sum
然后就可知道他的奇偶性了,至于更新哪四个点自己画个图感觉下就可以了
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#define inf 0x7ffffff
#define eps 1e-9
#define N 1005
#define pi acos(-1.0)
using namespace std;
int flag[N][N],c[N][N];
int lowbit(int x)
{
return x&(-x);
}
void update(int x,int y)
{
flag[x][y] = flag[x][y] == -1 ? 1 : -1;
int i,j;
for(i = x; i <= 1000; i+=lowbit(i))
for(j = y; j <= 1000; j+=lowbit(j))
c[i][j] += flag[x][y];
}
int sum(int x,int y)
{
int i,j;
int res = 0;
for(i = x; i > 0; i-=lowbit(i))
for(j = y; j > 0; j-=lowbit(j))
res += c[i][j];
return res;
}
int main()
{
//freopen("input.txt","r",stdin);
//freopen("output.txt","w",stdout);
int t;
scanf("%d",&t);
while(t--)
{
memset(flag,-1,sizeof(flag));
memset(c,0,sizeof(c));
int n,m;
scanf("%d%d",&n,&m);
while(m--)
{
char str[2];
int x1,y1,x2,y2;
scanf("%s",str);
if(*str == 'C'){
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(x1,y1);
update(x2+1,y2+1);
update(x1,y2+1);
update(x2+1,y1);
}
else {
scanf("%d%d",&x1,&y1);
printf("%d\n",sum(x1,y1)%2);
}
}
if(t)
printf("\n");
}
return 0;
}