楼教主的题被我做出来啦!
有一个01矩阵,两个操作:翻转从(x1, y1)到(x2, y2)的矩阵,查询(x, y)的值。
用二维树状数组记录每一个点的变换次数,按照奇偶性即可得到某个点现在的值。
变换时必须要从某点(x, y)更新到(n, n),以便更新后面的树状数组,因此,将(x1, y1)和(x2, y2)将矩阵分成四个区域,然后变换即可。
#include <cstdio>
#include <cstring>
const int maxn = 1000 + 5;
int a[maxn][maxn];
int n;
int lowbit(int x) {
return x & -x;
}
int sum(int x, int y) {
int sum = 0;
for (int i = x; i > 0; i -= lowbit(i)) {
for (int j = y; j > 0; j -= lowbit(j)) {
sum += a[i][j];
}
}
return sum;
}
void update(int x, int y) {
for (int i = x; i <= n; i += lowbit(i)) {
for (int j = y; j <= n; j += lowbit(j)) {
a[i][j]++;
}
}
}
int main(int argc, char const *argv[]) {
int x;
scanf("%d", &x);
while (x--) {
int t;
scanf("%d%d", &n, &t);
for (int i = 0; i < t; i++) {
getchar();
int ch = getchar();
if (ch == 'Q') {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", sum(x, y) & 1);
} else {
int x1, y1, x2, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
update(x1, y1);
update(x1, y2 + 1);
update(x2 + 1, y1);
update(x2 + 1, y2 + 1);
}
}
putchar('\n');
memset(a, 0, sizeof(a));
}
return 0;
}