题目大意:给你一个全是0的N*N矩阵,每次有两种操作:1将矩阵中一个子矩阵置反,2.查询某个点是0还是1
思路:裸的二维线段树
#include<iostream>
#include<cstdio>
#include <math.h>
#include<algorithm>
#include<string.h>
#include<queue>
#define MOD 1000003
#define maxn 4009
#define LL long long
using namespace std;
int n,num;
bool tree[maxn][maxn];
void add_y(int xx,int node,int l,int r,int ql,int qr)
{
if(ql<=l && r<=qr){tree[xx][node]^=1;return ;}
int mid=(l+r)>>1;
if(ql<mid)add_y(xx,node*2,l,mid,ql,qr);
if(qr>mid)add_y(xx,node*2+1,mid,r,ql,qr);
}
void add_x(int node,int l,int r,int ql,int qr,int y1,int y2)
{
if(ql<=l && r<=qr){add_y(node,1,1,n+1,y1,y2);return ;}
int mid=(l+r)>>1;
if(ql<mid)add_x(node*2,l,mid,ql,qr,y1,y2);
if(qr>mid)add_x(node*2+1,mid,r,ql,qr,y1,y2);
}
void query_y(int xx,int node,int l,int r,int y1)
{
if(tree[xx][node]==1)num++;
if(l+1==r)return ;
int mid=(l+r)>>1;
if(y1<mid)query_y(xx,node*2,l,mid,y1);
else query_y(xx,node*2+1,mid,r,y1);
}
void query_x(int node,int l,int r,int x1,int y1)
{
query_y(node,1,1,n+1,y1);
if(l+1==r)return ;
int mid=(l+r)>>1;
if(x1<mid)query_x(node*2,l,mid,x1,y1);
else query_x(node*2+1,mid,r,x1,y1);
}
int main()
{
int t,m,x1,x2,y1,y2;
char ch[10];
scanf("%d",&t);
while(t--)
{
memset(tree,0,sizeof(tree));
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
scanf("%s",ch+1);
if(ch[1]=='C')
{
scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
add_x(1,1,n+1,x1,x2+1,y1,y2+1);
}
else
{
num=0;
scanf("%d%d",&x1,&y1);
query_x(1,1,n+1,x1,y1);
printf("%d\n",num&1);
}
}
printf("\n");
}
return 0;
}