/**
* 这题太经典了!
* 二维树状数组:
* 要是对二维树状数组理解的不够是会完全想错的。
* 首先,树状数组也好,二维树状数组也好,update(int x) 一定是对数组或者二维数组
* 的维护,是在数组某个点上加上一个数后再对数组的维护! 而get_sum(int x, int y)是对二维区间
* 的求和操作。
* 而这题正好相反! 题意是改变区域内的值和求某个点的值!千万不要理解错了。。。(开始我就这么理解,一直在死胡同里绕啊绕。T^T)
* 准确理解完后,就是考虑如何运用二维树状数组解这题了,其实就是要在一个二维区间里的某几个点做标记(加一)
* 能够正确表示被置反的区间。
* 具体的: http://blog.csdn.net/zxy_snow/article/details/6264135 (非常详细,顺便膜拜下)
*/
#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <algorithm>
#define INF 0x7fffffff
#define MAXS 1001
#define LL long long
using namespace std;
int c[MAXS][MAXS];
int n;
int lowbit(int x) {
return x & (-x);
}
void update(int x, int y, int d) {
if(x <= 0 || y <= 0) return ;
for(int i = y; i <= n; i += lowbit(i)) {
for(int j = x; j <= n; j += lowbit(j))
c[i][j] += d;
}
}
int get_sum(int x, int y) {
if(x <= 0 || y <= 0) return 0;
int ret = 0;
for(int i = y; i > 0; i -= lowbit(i)) {
for(int j = x; j > 0; j -= lowbit(j))
ret += c[i][j];
}
return ret;
}
void init(int n) {
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
c[i][j] = 0;
}
int main()
{
int t, num;
scanf("%d", &t);
while(t -- ) {
scanf("%d%d", &n, &num);
init(n);
while(num --) {
getchar();
char cmd = getchar();
if(cmd == 'C') {
int x1, x2, y1, y2;
scanf("%d%d%d%d", &x1, &y1, &x2, &y2);
x1 ++, x2 ++, y1 ++ , y2 ++;
update(x2, y2, 1);
update(x1 - 1, y2, 1);
update(x2, y1 - 1, 1);
update(x1 - 1, y1 - 1, 1);
} else if(cmd == 'Q') {
int x, y, ans;
scanf("%d%d", &x, &y);
ans = get_sum(x, y);
ans %= 2;
printf("%d\n", ans);
}
}
if(t) printf("\n");
}
return 0;
}
poj 2155 Matrix 二维树状数组 (经典)
最新推荐文章于 2019-02-17 22:10:57 发布