【BZOJ】【P3226】【Sdoi2008】【校门外的区间】【题解】【线段树】

传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=3226

每个数之间加入一个数,就像这样
2 2.5 3 3.5 4
[2,3) -> [2,2.5]
(3,4] -> [3.5,4]
U 区间涂1
I 两侧区间涂0
D 区间涂0
C 两侧涂0,中间取反
S 区间取反

线段树搞搞就可以了

Code:

#include<bits/stdc++.h>
#define lson i<<1,l,mid
#define rson i<<1|1,mid+1,r
#define L i<<1
#define R i<<1|1
using namespace std;
const int maxn=65535*2+10;
int n=65535*2+1;
short a[maxn];
struct seg{
	struct node{
		short col,lazy,rev;
		node():col(0),lazy(-1),rev(0){};
	}t[maxn<<2];
	void pushdown(int i){
		if(t[i].rev){
			t[L].rev^=1;t[L].col^=1;
			if(~t[L].lazy)t[L].lazy^=1;
			
			t[R].rev^=1;t[R].col^=1;
			if(~t[R].lazy)t[R].lazy^=1;
			
			t[i].rev=0;
		}	
		if(t[i].lazy!=-1){
			t[L].lazy=t[R].lazy=t[i].lazy;
			t[L].col=t[R].col=t[i].lazy;
			t[i].lazy=-1;
		}
	}
	void Cov(int i,int l,int r,int l0,int r0,int col){
		if(l0>r0)return;
		if(l0<=l&&r0>=r){
			t[i].col=col;
			t[i].lazy=col;
			return;
		}int mid=(l+r)>>1;
		pushdown(i);
		if(l0<=mid)Cov(lson,l0,r0,col);
		if(r0>mid)Cov(rson,l0,r0,col);
	}
	void Rev(int i,int l,int r,int l0,int r0){
		if(l0>r0)return;
		if(l0<=l&&r0>=r){
			t[i].col^=1;
			if(~t[i].lazy)t[i].lazy^=1;
			t[i].rev^=1;
			return;
		}int mid=(l+r)>>1;
		pushdown(i);
		if(l0<=mid)Rev(lson,l0,r0);
		if(r0>mid)Rev(rson,l0,r0);
	}
	void print(int i,int l,int r){
		if(l==r){a[l]=t[i].col;return;}
		int mid=(l+r)>>1;
		pushdown(i);
		print(lson);print(rson);
	}
}T;
#undef L
#undef R
struct segment{
	int l,r;
	char L,R;
}anss[maxn];
int size;
int main(){
	char op[2];
	int l,r;char L,R;
	while(~scanf("%s %c%d,%d%c",op,&L,&l,&r,&R)){
		l<<=1;r<<=1;
		l++;r++;
		l+=L=='(';r-=R==')';
		if(op[0]=='U')T.Cov(1,1,n,l,r,1);
		else if(op[0]=='I')T.Cov(1,1,n,1,l-1,0),T.Cov(1,1,n,r+1,n,0);
		else if(op[0]=='D')T.Cov(1,1,n,l,r,0);
		else if(op[0]=='C')T.Cov(1,1,n,1,l-1,0),T.Cov(1,1,n,r+1,n,0),T.Rev(1,1,n,l,r);
		else if(op[0]=='S')T.Rev(1,1,n,l,r);		
	}T.print(1,1,n);
	for(int i=1;i<=n;i++){
		int j=i-1;
		if(!a[i-1]&&a[i]){
			size++;
			anss[size].l=j/2;
			anss[size].L=j%2==0?'[':'(';
		}
		if(a[i]&&!a[i+1]){
			anss[size].r=j/2+j%2;
			anss[size].R=j%2==0?']':')';		
		}
	}
	if(!size)printf("empty set");
	for(int i=1;i<=size;i++){
		printf("%c%d,%d%c",anss[i].L,anss[i].l,anss[i].r,anss[i].R);if(i-size)putchar(' ');
	}
	return 0;
}


你可能感兴趣的:(bzoj)