题意:
官方有中文
思路:
首先要处理括号的问题,那么我们就可以离散下坐标,让每个坐标扩大两倍来表示,这样就能解决括号的问题了。
U:把区间[l,r]覆盖成1
I:把[-∞,l)(r,∞]覆盖成0
D:把区间[l,r]覆盖成0
C:把[-∞,l)(r,∞]覆盖成0 , 且[l,r]区间0/1互换
S:[l,r]区间0/1互换
线段树的值1,0表示这一段全为0或者1,-1表示无法确定,只要加一个异或标记就能完成所有操作,在覆盖的时候,我们可以直接覆盖掉异或标记,最后一次查询,同时用一个数组表示某个数值的状态即可
错误及反思:
离散后坐标时可能出现负数的,这里要判断下,同时,由于线段树的一些问题,数组要开大一些。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int N =131072;
bool did[131072];
int segtree[131072*5],Xor[131072*5];
void pushdown(int l,int r,int rt)
{
if(segtree[rt]!=-1)
{
segtree[rt<<1]=segtree[rt];
segtree[rt<<1|1]=segtree[rt];
Xor[rt<<1]=0;
Xor[rt<<1|1]=0;
return ;
}
if(Xor[rt])
{
if(segtree[rt<<1]!=-1){
segtree[rt<<1]^=1;
}
else{
Xor[rt<<1]++;
Xor[rt<<1]%=2;
}
if(segtree[rt<<1|1]!=-1){
segtree[rt<<1|1]^=1;
}
else{
Xor[rt<<1|1]++;
Xor[rt<<1|1]%=2;
}
Xor[rt]=0;
}
}
void query(int l,int r,int rt)
{
if(segtree[rt]!=-1)
{
if(segtree[rt]==1)
{
for(int i=l;i<=r;i++)
did[i]=true;
}
return ;
}
pushdown(l,r,rt);
int m=(l+r)/2;
query(lson);
query(rson);
}
void update(int L,int R,int v,int l,int r,int rt)
{
if(L<=l&&R>=r)
{
if(v==0||v==1)
{
segtree[rt]=v;
Xor[rt]=0;
}
else
{
if(segtree[rt]!=-1){
segtree[rt]^=1;
}
else{
Xor[rt]++;
Xor[rt]%=2;
}
}
return ;
}
pushdown(l,r,rt);
int m=(l+r)/2;
if(L<=m) update(L,R,v,lson);
if(R>m) update(L,R,v,rson);
if(segtree[rt<<1]==segtree[rt<<1|1])
segtree[rt]=segtree[rt<<1];
else segtree[rt]=-1;
}
int main()
{
char T[101],t[10];
int a,b;
while(scanf("%s %c%d%c%d%c",T,&t[0],&a,&t[1],&b,&t[2])!=EOF)
{
a*=2,b*=2;
if(t[0]=='(') a++;
if(t[2]==')') b--;
if(a>b)
{
if(T[0] == 'C'||T[0] == 'I')
update(0,N,0,0,N,1);
continue;
}
if(T[0]=='U')
update(a,b,1,0,N,1);
else if(T[0]=='I'){
if(a>0) update(0,a-1,0,0,N,1);
update(b+1,N,0,0,N,1);
}
else if(T[0]=='D')
update(a,b,0,0,N,1);
else if(T[0]=='C'){
if(a>0) update(0,a-1,0,0,N,1);
update(b+1,N,0,0,N,1);
update(a,b,-1,0,N,1);
}
else update(a,b,-1,0,N,1);
}
query(0,N,1);
int num=0;
for(int i=0;i<=N;i++)
{
if(did[i])
{
if(num) printf(" ");
if(i%2) printf("(%d,",(i)/2);
else printf("[%d,",(i)/2);
num++;
while(did[i])
i++;
if(i%2) printf("%d]",(i)/2);
else printf("%d)",(i)/2);
}
}
if(num==0) puts("empty set");
else puts("");
}