操作含义:
我们一个一个操作来分析:(用0和1表示是否包含区间,-1表示该区间内既有包含又有不包含)
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[ID]=1表示用1覆盖去见,COVER[ID]=0,表示用0覆盖区间,COVER[ID]=-1,表示其子区间既有1覆盖又有0覆盖的请款,
对于每个节点使用覆盖或者异或操作标记延迟,1:如果一个区间遇上覆盖标记,则其异或标清空,2:如果一个区间是覆盖标记,pushdown操作使得其孩子区间的异或标志位变为0,孩子的覆盖标志等于其父代的标志。3如果其异或标记存在,Pushdown操作检查孩子的的覆盖标志,如果存在,则孩子覆盖标志直接变为原来的反,否者孩子的异或标志变为原来的反,异或1可以取得原来的反,4:操作保证每一个节点只存在一个覆盖标记或者异标志,
#include<cstdio> #include<cstdlib> #include<cmath> #include<cstring> #define MAXN 131072 int c_cover[MAXN<<2],c_xor[MAXN<<2]; bool hash[MAXN+10]; void update(char op,int left,int right,int l,int r,int id); void f_xor(int id); void push_down(int id); void push_down(int id); void query(int l,int r,int id); int main() { char op,c_left,c_right; int i,left,right; c_xor[1]=0; c_cover[1]=0; while(~scanf("%c %c%d,%d%c\n",&op,&c_left,&left,&right,&c_right)) { left<<=1; right<<=1; if(c_left=='(') left++; if(c_right==')') right--; if(left>right) { if(op=='C'||op=='I') c_cover[1]=c_xor[1]=0; } else update(op,left,right,0,MAXN,1); } query(0,MAXN,1); int a=-1,b; bool flag=false; for(i=0;i<=MAXN;i++) { if(hash[i]) { b=i; if(a==-1)a=i; } else if(a!=-1) { if(flag) printf(" "); printf("%c%d,%d%c",a&1?'(':'[',a>>1,(b+1)>>1,b&1?')':']'); flag=true; a=-1; } } if(!flag) printf("empty set"); puts(""); } void update(char op,int left,int right,int l,int r,int id) { if(left<=l&&right>=r) { if(op=='U') { c_cover[id]=1; c_xor[id]=0; } else if(op=='D') { c_cover[id]=0; c_xor[id]=0; } else if(op=='S'||op=='C') { f_xor(id); } return ; } push_down(id); int mid=(l+r)>>1; if(left<=mid) update(op,left,right,l,mid,id<<1); else if(op=='I'||op=='C') { c_cover[id<<1]=0; c_xor[id<<1]=0; } if(right>mid) { update(op,left,right,mid+1,r,id<<1|1); } else if(op=='I'||op=='C') { c_cover[id<<1|1]=0; c_xor[id<<1|1]=0; } } void f_xor(int id) { if(c_cover[id]!=-1) c_cover[id]^=1; else c_xor[id]^=1; } void push_down(int id) { if(c_cover[id]!=-1) { c_cover[id<<1]=c_cover[id<<1|1]=c_cover[id]; c_xor[id<<1]=c_xor[id<<1|1]=0; c_cover[id]=-1; } if(c_xor[id]) { f_xor(id<<1); f_xor(id<<1|1); c_xor[id]=0; } } void query(int l,int r,int id) { if(c_cover[id]==1) { int i; for(i=l;i<=r;i++) { hash[i]=1; } return ; } else if(c_cover[id]==0) return ; if(l==r) return ; push_down(id); int mid=(l+r)>>1; query(l,mid,id<<1); query(mid+1,r,id<<1|1); }