//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 二維線段樹 奇妙的成段更新 單點查詢
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.