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互换
cover记录成段覆盖,xo记录互换
当一个节点得到覆盖标记时把异或标记清空
当一个节点得到异或标记的时候,先判断覆盖标记,如果是0或1,直接改变一下覆盖标记,不然的话改变异或标记
开区间闭区间只要数字乘以2就可以处理(偶数表示端点,奇数表示两端点间的区间)
例: [2,3]=4->6 (2,3)=5->5 [2,3)=4->5
最后用hash查找一下即可
注意边界判断
PS:翻译了半天才发现题目竟然可以选择中文.........
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
#include "iostream"
#include "algorithm"
using namespace std;
struct comp
{
int num1,num2;
char l,r,op;
} sca[300010];
struct comp1
{
int l,r,cover,mid,xo,x;
} data[300010];
int first;
int hash[300010];
void Pushdown(int k)
{
if (data[k].l==data[k].r) return ;
if (data[k].cover!=-1)
{
data[k*2].cover=data[k*2+1].cover=data[k].cover;
data[k*2].xo=data[k*2+1].xo=0;
data[k*2].x=data[k*2+1].x=data[k].cover;
data[k].cover=-1;
return ;
}
if (data[k].xo%2!=0)
{
if (data[k*2].cover==1) data[k*2].cover=0; // 覆盖标记不为-1时,直接改变覆盖标记
else
if (data[k*2].cover==0) data[k*2].cover=1;
else data[k*2].xo++;
if (data[k*2+1].cover==0) data[k*2+1].cover=1;
else
if (data[k*2+1].cover==1) data[k*2+1].cover=0;
else data[k*2+1].xo++;
if (data[k*2].x==1)
data[k*2].x=0;
else
if (data[k*2].x==0)
data[k*2].x=1;
if (data[k*2+1].x==1)
data[k*2+1].x=0;
else
if (data[k*2+1].x==0)
data[k*2+1].x=1;
data[k].xo=0;
}
}
void build(int l,int r,int k)
{
data[k].l=l;
data[k].r=r;
data[k].mid=(l+r)/2;
data[k].cover=-1;
data[k].xo=0;
data[k].x=0;
if (l==r) return ;
build(l,data[k].mid,k*2);
build(data[k].mid+1,r,k*2+1);
}
void update_cover(int l,int r,int k,int op)
{
if (data[k].l==l && data[k].r==r)
{
data[k].cover=op;
data[k].x=op;
data[k].xo=0;
return ;
}
Pushdown(k);
if (r<=data[k].mid) update_cover(l,r,k*2,op);
else
if (l>data[k].mid) update_cover(l,r,k*2+1,op);
else
{
update_cover(l,data[k].mid,k*2,op);
update_cover(data[k].mid+1,r,k*2+1,op);
}
if (data[k*2].x==data[k*2+1].x && data[k*2].x!=-1) data[k].x=data[k*2].x; else data[k].x=-1;
}
void update_xor(int l,int r,int k)
{
if (data[k].l==l && data[k].r==r)
{
if (data[k].x==0) data[k].x=1;
else
if (data[k].x==1) data[k].x=0;
if (data[k].cover==0) data[k].cover=1 ; // 覆盖标记不为-1时,直接改变覆盖标记
else
if (data[k].cover==1) data[k].cover=0;
else data[k].xo++;
return ;
}
Pushdown(k);
if (r<=data[k].mid) update_xor(l,r,k*2);
else
if (l>data[k].mid) update_xor(l,r,k*2+1);
else
{
update_xor(l,data[k].mid,k*2);
update_xor(data[k].mid+1,r,k*2+1);
}
if (data[k*2].x==data[k*2+1].x && data[k*2].x!=-1) data[k].x=data[k*2].x; else data[k].x=-1;
}
void search(int k)
{
int i;
if (data[k].x==1)
{
first=0;
for (i=data[k].l;i<=data[k].r;i++)
hash[i]=1;
return ;
}
else
if (data[k].x==0) return ;
else
{
Pushdown(k);
search(k*2);
search(k*2+1);
}
}
int main()
{
int s,e,n,a,b,i,m;
char ch[10];
n=0;
m=0;
while (scanf("%s",ch)!=EOF)
{
getchar();
n++;
sca[n].op=ch[0];
scanf("%c%d,%d%c\n",&sca[n].l,&sca[n].num1,&sca[n].num2,&sca[n].r);
if (sca[n].num1>m) m=sca[n].num1;
if (sca[n].num2>m) m=sca[n].num2;
}
build(0,m*2,1);
for (i=1;i<=n;i++)
{
a=sca[i].num1*2;
b=sca[i].num2*2;
if (sca[i].l=='(') a++;
if (sca[i].r==')') b--;
if (sca[i].op=='U')
{
if (a<=b) update_cover(a,b,1,1);
}
if (sca[i].op=='I')
{
if (a<=b)
{
if (a!=0) update_cover(0,a-1,1,0);
if (b!=m*2) update_cover(b+1,m*2,1,0);
}
else update_cover(0,m*2,1,0);
}
if (sca[i].op=='D')
{
if (a<=b)
update_cover(a,b,1,0);
}
if (sca[i].op=='C')
{
if (a<=b)
{
update_xor(a,b,1);
if (a!=0) update_cover(0,a-1,1,0);
if (b!=m*2) update_cover(b+1,m*2,1,0);
}
else update_cover(0,m*2,1,0);
}
if (sca[i].op=='S')
{
if (a<=b) update_xor(a,b,1);
}
}
first=1;
memset(hash,0,sizeof(hash));
search(1);
if (first==1) printf("empty set");
else
{
s=-1;
for (i=0;i<=m*2;i++)
if (hash[i]==1)
{
if (s==-1) s=i;
e=i;
}
else
if (s!=-1)
{
if (first==1) printf(" ");else first=1;
if (s%2==0) printf("["); else printf("(");
printf("%d,",s/2);
if (e%2==0) printf("%d]",e/2); else printf("%d)",e/2+1);
s=-1;
}
if (s!=-1)
{
if (first==1) printf(" ");else first=1;
if (s%2==0) printf("["); else printf("(");
printf("%d,",s/2);
if (e%2==0) printf("%d]",e/2); else printf("%d)",e/2+1);
s=-1;
}
}
}