tozangezan's diary

勝手にソースコードをコピペして利用しないでください。

PKU 3225 Help with Intervals

遅延系のsegtreeの練習を定期的にしている気がする。
し、デバッグに時間がかかりました。
やることは区間に1を代入、0を代入、xorだけで十分。ほかのはこの三つの組み合わせでいける。というか2つで(1を代入とxor)十分だと思う。

#include<stdio.h>
#include<algorithm>
using namespace std;
char str[10];
char str2[100];
int lt[262144];
int xr[262144];
void update(int a,int b,int c,int d,int e,int type){
	if(d<a||b<c)return;
	if(c<=a&&b<=d){
		if(type==0){ // plus
			xr[e]=0;
			lt[e]=1;
		}
		if(type==1){ // minus
			xr[e]=0;
			lt[e]=0;
		}
		if(type==2){ // xor
			xr[e]=!xr[e];
		}
		return;
	}
	if(~lt[e]){
		lt[e]^=xr[e];
		lt[e*2]=lt[e*2+1]=lt[e];
		lt[e]=-1;
		xr[e]=xr[e*2]=xr[e*2+1]=0;
	}else{
		xr[e*2]^=xr[e];
		xr[e*2+1]^=xr[e];
		xr[e]=0;
	}
	update(a,(a+b)/2,c,d,e*2,type);
	update((a+b)/2+1,b,c,d,e*2+1,type);
}
int get(int a){
	int L=0;
	int R=131072;
	int e=1;
	while(L+1<R){
		if(~lt[e]){
			lt[e]^=xr[e];
			lt[e*2]=lt[e*2+1]=lt[e];
			lt[e]=-1;
			xr[e]=xr[e*2]=xr[e*2+1]=0;
		}else{
			xr[e*2]^=xr[e];
			xr[e*2+1]^=xr[e];
			xr[e]=0;
		}
		int M=(L+R)/2;
		if(a<M){
			R=M;
			e*=2;
		}else{
			L=M;
			e=e*2+1;
		}
	}
	return lt[e]^xr[e];
}
int main(){
	while(~scanf("%s",str)){
		scanf("%s",str2);
		int A=0;
		int at=1;
		while(str2[at]!=','){
			A*=10;
			A+=str2[at]-'0';
			at++;
		}
		int B=0;
		at++;
		while(str2[at]!=']'&&str2[at]!=')'){
			B*=10;
			B+=str2[at]-'0';
			at++;
		}
		A*=2;B*=2;
		if(str2[0]=='(')A++;
		if(str2[at]==')')B--;

		if(A>131070||B<0)continue;
		if(str[0]=='U'){
			update(0,131071,A,B,1,0);
		}
		if(str[0]=='I'){
			if(A)update(0,131071,0,A-1,1,1);
			update(0,131071,B+1,131070,1,1);
		}
		if(str[0]=='D'){
			update(0,131071,A,B,1,1);
		}
		if(str[0]=='C'){
			if(A)update(0,131071,0,A-1,1,0);
			update(0,131071,B+1,131070,1,0);
			update(0,131071,0,131070,1,2);
		}
		if(str[0]=='S'){
			update(0,131071,A,B,1,2);
		}
	}
	bool ok=false;
	int last=-1;
	for(int i=0;i<131072;i++){
		if(get(i)){
			if(last==-1){
				last=i;
			}
		}else{
			if(~last){
				if(ok)printf(" ");
				ok=true;
				if(last%2)printf("(");
				else printf("[");
				printf("%d,",last/2);
				
				printf("%d",(i)/2);
				if(i%2)printf("]");
				else printf(")");
			}
			last=-1;
		}
	}
	if(!ok)printf("empty set");
	printf("\n");
	
}