楼教主出的题,先orz下。
这道题是修改区间询问点的题,由于二维线段树编程复杂度高,所以可以考虑用二维的数状数组实现,
使用C数组来记录翻转次数,查询的时候mod 2即为当前的数,更新的话需要将(x2,y2),(x1-1,y2),(x2,y1 - 1),(x1 - 1,y1 - 1)这四个矩形区域翻转,最后只有(x1,y1)->(x2,y2)这个矩形取反次数为奇数次,其余为偶数次,这样就实现了更新操作。
代码:
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn = 1000 + 10;
int c[maxn][maxn];
int n,m,T;
int lowbit(int x)
{
return x & (-x);
}
void update(int x,int y)
{
for(int i = x;i > 0;i -= lowbit(i))
for(int k = y;k > 0;k -= lowbit(k))
c[i][k]++;
}
int get(int x,int y)
{
int sum = 0;
for(int i = x;i <= n;i += lowbit(i))
for(int k = y;k <= n;k += lowbit(k))
sum += c[i][k];
return sum;
}
void init()
{
freopen("poj2155.in","r",stdin);
freopen("poj2155.out","w",stdout);
}
void readdata()
{
scanf("%d",&T);
while(T--)
{
memset(c,0,sizeof(c));
scanf("%d%d",&n,&m);
for(int i = 1;i <= m;i++)
{
char op[2];
scanf("%s",op);
if(op[0] == 'C')
{
int x1,y1,x2,y2;
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
update(x2,y2);
update(x1-1,y1-1);
update(x1-1,y2);
update(x2,y1-1);
}
else
{
int x,y;
scanf("%d%d",&x,&y);
printf("%d\n",get(x,y) % 2);
}
}
printf("\n");
}
}
int main()
{
init();
readdata();
return 0;
}