题意:矩阵默认全为 0,操作是对输入的两个点构成的矩形内所有元素取反,询问是问某个点是 1 还是 0。
二维树状数组解决此题非常巧妙,更新矩形四个顶点。
如果想不明白的话,可以先考虑一维的情况:对[x, y] 区间内所有数取反,可以看成对树状数组的 a[ x ]和 a[ y+1 ]加一。
详解建议参考:浅谈信息学竞赛中的“0”和“1”
#include<iostream> #include<cmath> #include<queue> #include<cstring> #include<string> #include<map> #include<stack> #include<set> #include<cstdio> #include<algorithm> using namespace std; int n; int a[1010][1010]; int lowbit(int x){ return x&(-x); } void add2(int x,int y,int num){//二维 for(int i = x; i <= n; i += lowbit(i)) for(int j = y; j <= n; j += lowbit(j)) a[i][j] += num; } int sum2(int x,int y){ int res = 0; for(int i = x; i > 0; i -= lowbit(i)) for(int j = y; j > 0; j -= lowbit(j)) res += a[i][j]; return res; } int main(){ //freopen("a.txt", "r", stdin); int T, x1, y1, x2, y2, m; cin >>T; char s[5]; while(T--){ memset(a, 0, sizeof(a)); scanf("%d%d", &n, &m); while(m--){ scanf("%s", s); if(s[0] == 'C'){ scanf("%d%d%d%d", &x1, &y1, &x2, &y2); add2(x1, y1, 1); add2(x2+1, y2+1, 1); add2(x1, y2+1, 1); add2(x2+1, y1, 1); }else{ scanf("%d%d", &x1, &y1); printf("%dn", sum2(x1,y1)%2); } } cout <<endl; } return 0; }