标签:
题比较有趣,输入输出比较麻烦。
每个点拆成两个,线段树维护。(这题难点真的在输入输出)
#include<bits/stdc++.h>
#define N (1<<17)
#define M (l+r>>1)
#define P (k<<1)
#define S (k<<1|1)
#define K l,r,k
#define L l,M,P
#define R M+1,r,S
#define Z int l=0,int r=N,int k=1
int u[N<<2],v[N<<2],a[N<<2];
template<int d>
void same(int k){
u[k]=d;
v[k]=0;
}
void flip(int k){
(~u[k]?u[k]:v[k])^=1;
}
void (*operate[3])(int)
={same<0>,same<1>,flip};
void devolve(int k){
int d=v[k]?2:u[k];
if(~d){
operate[d](P);
operate[d](S);
v[k]=0;
u[k]=-1;
}
}
void A(int d,int s,int t,Z){
if(s==l&&t==r)
operate[d](k);
else{
devolve(k);
if(t<=M)
A(d,s,t,L);
else if(s>M)
A(d,s,t,R);
else{
A(d,s,M,L);
A(d,M+1,t,R);
}
}
}
void finish(Z){
if(~u[k])
for(int i=l;i<=r;++i)
a[i]=u[k];
else{
devolve(k);
finish(L);
finish(R);
}
}
bool empty(){
for(int i=0;i<=N;++i)
if(a[i])
return 0;
return 1;
}
int main(){
memset(u,-1,sizeof u);
char d[2],b[16];
while(~scanf("%s%s",d,b)){
char u,v;
int s,t;
sscanf(b,"%c%d,%d%c",
&u,&s,&t,&v);
s=s*2+(u==‘(‘);
t=t*2-(v==‘)‘);
if(s>t)
continue;
if(*d^‘I‘&&*d^‘C‘)
A(*d==‘S‘
?2:*d==‘U‘,s,t);
else{
if(*d^‘I‘)
A(2,s,t);
if(s^0)
A(0,0,s-1);
if(t^N)
A(0,t+1,N);
}
}
finish();
if(empty())
puts("empty set");
else
for(int i=0;i<=N;++i){
if((!i||!a[i-1])&&a[i])
printf("%c%d,",
i&1?‘(‘:‘[‘,i>>1);
if(a[i]&&!a[i+1])
printf("%d%c ",
i+1>>1,i&1?‘)‘:‘]‘);
}
}
bzoj3226: [Sdoi2008]校门外的区间 线段树
标签:
原文地址:http://www.cnblogs.com/f321dd/p/5496069.html