POJ 2155 Matrix 二維線段樹 奇妙的成段更新 單點查詢

//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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章