题目链接
题目大意:起初一个全0矩阵,q个操作,可以修改(x1,y1)到(x2,y2)这个子矩阵,让其中元素翻转(0变1,1变0),每次询问单点a[x1][y1]的信息。
思路:碰到这种区间修改的第一反应就是线段树和差分数组,但二维线段树让谁打谁都不想打,代码不少,那就为了方便调试只能差分数组了。
我觉得这篇博客讲的不错,二维差分不想画图理解的话就看这个把。博客地址
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int N=1e3+10;
int c[N][N],n,q;
inline int lowbit(int x){
return x&(-x);}
void add(int x,int y,int val)
{
int yy=y;
while(x<=n)
{
yy=y;
while(yy<=n)
{
c[x][yy]+=val;
yy+=lowbit(yy);
}
x+=lowbit(x);
}
}
int query(int x,int y)
{
int res=0,yy=y;
while(x>0)
{
yy=y;
while(yy>0)
{
res+=c[x][yy];
yy-=lowbit(yy);
}
x-=lowbit(x);
}
return res;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(c,0,sizeof(c));
scanf("%d%d",&n,&q);
char op[5];
int x1,x2,y1,y2;
for(int i=1;i<=q;i++)
{
scanf("%s",op);
if(op[0]=='C')
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
add(x1,y1,1);
add(x2+1,y2+1,1);
add(x2+1,y1,-1);
add(x1,y2+1,-1);
}
else
{
scanf("%d%d",&x1,&y1);
printf("%d\n",query(x1,y1)%2);
}
}
printf("\n");
}
return 0;
}