//POJ 2155 Matrix 二维线段树 奇妙的成段更新 单点查询
/*
题意:
有一个n*n的矩阵,初始化全部为0。有2中操作;
1、给一个子矩阵,将这个子矩阵里面所有的0变成1,1变成0
2、询问某点的值
思路:
二维线段树,一维线段树的成段更新需要lazy。
引申到二维线段树应该需要一个lazy,一个sublazy,可是这里什么都不用。
奇妙之处在于这题的操作是异或,当某一段区间需要异或操作时候,
不必更新到它所有的叶子结点,可以像lazy那样父结点异或后就返回
只要在查询时从根节点开始异或,而不是直接查叶子结点,这样相当于将lazy储存在父结点上
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define N 1005
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
int sum[N<<2][N<<2];
int n,m,ans;
void SubBuild(int rt,int l,int r,int t){
sum[t][rt] = 0;
if(l!=r){
int mid = (l + r) >> 1;
SubBuild(lson,t);
SubBuild(rson,t);
}
}
void Build(int rt,int l,int r){
SubBuild(1,1,n,rt);
if(l != r){
int mid = (l + r) >> 1;
Build(lson);
Build(rson);
}
}
void SubUpdate(int rt,int l,int r,int LY,int RY,int t){
if(LY <= l && RY >= r)
sum[t][rt] ^= 1;
else{
int mid = (l + r) >> 1;
if(LY <= mid) SubUpdate(lson,LY,RY,t);
if(RY > mid) SubUpdate(rson,LY,RY,t);
}
}
void Update(int rt,int l,int r,int LX,int RX,int LY,int RY){
if(LX <= l && RX >= r)
SubUpdate(1,1,n,LY,RY,rt);
else{
int mid = (l + r) >> 1;
if(LX <= mid) Update(lson,LX,RX,LY,RY);
if(RX > mid) Update(rson,LX,RX,LY,RY);
}
}
void SubQuery(int rt,int l,int r,int y,int t){
ans ^= sum[t][rt];//这里是异或!!!
if(l!=r){
int mid = (l + r) >> 1;
if(y <= mid) SubQuery(lson,y,t);
else SubQuery(rson,y,t);
}
}
void Query(int rt,int l,int r,int x,int y){
SubQuery(1,1,n,y,rt);
if(l!=r){
int mid = (l + r) >> 1;
if(x <= mid) Query(lson,x,y);
else Query(rson,x,y);
}
}
int main(){
int T,ca = 1;
char op[5];
int a,b,c,d;
scanf("%d",&T);
while(T--){
scanf("%d %d",&n,&m);
Build(1,1,n);
if(ca++ != 1)
puts("");
while(m--){
scanf("%s",op);
if(op[0] == 'C'){
scanf("%d %d %d %d",&a,&b,&c,&d);
Update(1,1,n,a,c,b,d);
}
else{
scanf("%d %d",&a,&b);
ans = 0;
Query(1,1,n,a,b);
printf("%d\n",ans);
}
}
}
return 0;
}
POJ 2155 Matrix 二维线段树 奇妙的成段更新 单点查询
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.