类型:二维线段树
题目:给定一个n*n的矩阵由元素0和1组成,对于操作C x1 y1 x2 y2表示对子矩阵(x1,y1)到(x2,y2)各个
元素按位取反,操作Q x y表示查询(x,y)位置的元素,输出查询的结果
来源:POJ Monthly,Lou Tiancheng
思路:对每一次C操作,更新线段树相对应根节点的值,对其取反。对每一次Q操作,从根节点开始往下查找,如
果当前根值为1,则执行一次取反操作[每个路径上的根的操作对其都会产生作用]
!!!右根不能用root << 1 + 1表示,'+'运算符优先级大于'<<'
// poj 2155 Matrix
// 9156K 797MS
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
#define FOR(i,a,b) for(i = (a); i < (b); ++i)
#define FORE(i,a,b) for(i = (a); i <= (b); ++i)
#define CLR(a,b) memset(a,b,sizeof(a))
const int MAXN = 1010;
int T, n, c, sum;
int x1, y1, x2, y2;
bool tree[3 * MAXN][3 * MAXN];
void sub_update(int preroot, int root, int l, int r, int y1, int y2) {
if(l == y1 && r == y2) {
tree[preroot][root] ^= 1;
return ;
}
int mid = (l + r) >> 1;
if(mid >= y2)
sub_update(preroot, root << 1, l, mid, y1, y2);
else if(mid < y1)
sub_update(preroot, root << 1 | 1, mid + 1, r, y1, y2);
else {
sub_update(preroot, root << 1, l, mid, y1, mid);
sub_update(preroot, root << 1 | 1, mid + 1, r, mid + 1, y2);
}
}
void update(int root, int l, int r, int x1, int x2) {
if(l == x1 && r == x2) {
sub_update(root, 1, 1, n, y1, y2);
return ;
}
int mid = (l + r) >> 1;
if(mid >= x2)
update(root << 1, l, mid, x1, x2);
else if(mid < x1)
update(root << 1 | 1, mid + 1, r, x1, x2);
else {
update(root << 1, l, mid, x1, mid);
update(root << 1 | 1, mid + 1, r, mid + 1, x2);
}
}
void sub_query(int preroot, int root, int l, int r, int y) {
sum ^= tree[preroot][root];
if(l == r)
return ;
int mid = (l + r) >> 1;
if(mid >= y)
sub_query(preroot, root << 1, l, mid, y);
else
sub_query(preroot, root << 1 | 1, mid + 1, r, y);
}
void query(int root, int l, int r, int x) {
sub_query(root, 1, 1, n, y1);
if(l == r)
return ;
int mid = (l + r) >> 1;
if(mid >= x)
query(root << 1, l, mid, x);
else
query(root << 1 | 1, mid + 1, r, x);
}
int main()
{
char ch;
int i;
scanf("%d", &T);
while(T--) {
CLR(tree, false);
scanf("%d %d", &n, &c);
FOR(i, 0, c) {
scanf(" %c", &ch);
if(ch == 'C') {
scanf("%d %d %d %d", &x1, &y1, &x2, &y2);
update(1, 1, n, x1, x2);
}
else {
scanf("%d %d", &x1, &y1);
sum = 0;
query(1, 1, n, x1);
printf("%d\n", sum);
}
}
if(T != 0)
printf("\n");
}
return 0;
}