题意:
一个初始为0的n*n矩阵,有m个操作,c为区间取反,q为单点查询
解题思路:
对于区间更新单点查询的题目,用树状数组是极好的,更新区间(a,b)我们update(a, 1), update(b+1, -1),然后查询的时候直接输出query(x)就是单点的值。
这个题需要扩展到二维,其实解法类似, update(x1, y1, 1); update(x2+1, y1, -1);update(x1, y2+1, -1);update(x2+1, y2+1, 1); 就可以。
这个题的操作由于是取反,不是简单的加减,所以需要转换一下,我们记录取反的次数,最后每个点取反了奇数次就是1,取反了偶数次就是0。
代码:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
int bit[1005][1005];
int n;
int lowbit(int x)
{
return -x&x;
}
void update(int x, int y, int z)
{
int i, j;
for(i=x; i<=n; i+=lowbit(i))
{
for(j=y; j<=n; j+=lowbit(j))
{
bit[i][j]+=z;
// printf("%d %d\n", i, j);
}
}
return;
}
int query(int x, int y)
{
int res=0, i, j;
for(i=x; i>0; i-=lowbit(i))
{
for(j=y; j>0; j-=lowbit(j))
{
res+=bit[i][j];
}
}
return res;
}
int main()
{
int i, j, t, m;
char x;
cin>>t;
while(t--)
{
scanf("%d%d", &n, &m);
for(i=0; i<=n; i++)for(j=0; j<=i; j++)bit[i][j]=bit[j][i]=0;
for(i=0; i<m; i++)
{
scanf("\n%c", &x);
int sum=0,x1, y1, x2, y2;
if(x=='C')
{
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
if(x1>x2 ||(x1==x2 && y1>y2))
{
swap(x1, x2);
swap(y1, y2);
}
// printf("%d %d %d %d\n", x1, y1, x2, y2);
update(x1, y1, 1);
update(x2+1, y1, -1);
update(x1, y2+1, -1);
update(x2+1, y2+1, 1);
}
else
{
scanf("%d%d", &x1, &y1);
// printf("%d\n", query(x1, y1));
printf("%d\n", query(x1, y1)&1);
}
}
if(t)printf("\n");
}
}