题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3226
题意:初始集合S为空。模拟四种集合操作:集合并、交、差、补集并。
思路:区间有开区间闭区间,首先区间左右都乘以2,这样闭区间在偶数位置,开区间在奇数位置。然后就是区间染色颜色反转两个操作。注意区间染色时,若有反转标记则清除;反转时若有染色标记则直接将染色反转即可。
const int N=70005; struct node { int L,R; int re,color; void fill(int c) { if(re) re=0; color=c; } void reverse() { if(color!=-1) color^=1; else { re^=1; } } }; node a[N<<3]; void build(int t,int L,int R) { a[t].L=L; a[t].R=R; a[t].color=0; a[t].re=0; if(L==R) return; int M=(L+R)>>1; build(t<<1,L,M); build(t<<1|1,M+1,R); } void pushDown(int t) { if(a[t].L==a[t].R) return; if(a[t].color!=-1) { a[t<<1].fill(a[t].color); a[t<<1|1].fill(a[t].color); a[t].color=-1; } if(a[t].re) { a[t<<1].reverse(); a[t<<1|1].reverse(); a[t].re=0; } } void fill(int t,int L,int R,int c) { if(L>R) return; if(a[t].L==L&&a[t].R==R) { a[t].fill(c); return; } pushDown(t); int M=(a[t].L+a[t].R)>>1; if(R<=M) fill(t<<1,L,R,c); else if(L>M) fill(t<<1|1,L,R,c); else { fill(t<<1,L,M,c); fill(t<<1|1,M+1,R,c); } } void rev(int t,int L,int R) { if(L>R) return; if(a[t].L==L&&a[t].R==R) { a[t].reverse(); return; } pushDown(t); int M=(a[t].L+a[t].R)>>1; if(R<=M) rev(t<<1,L,R); else if(L>M) rev(t<<1|1,L,R); else { rev(t<<1,L,M); rev(t<<1|1,M+1,R); } }; vector<pair<int,int> > V; void dfs(int t) { if(a[t].color==1) { V.pb(MP(a[t].L,a[t].R)); return; } if(a[t].color==0) return; pushDown(t); dfs(t<<1); dfs(t<<1|1); } int main() { int n=N<<1; build(1,0,n); char op,ll,rr; int l,r; while(scanf("%c %c%d,%d%c\n",&op,&ll,&l,&r,&rr)!=-1) { l<<=1; r<<=1; if(ll=='(') l++; if(rr==')') r--; if(op=='U') fill(1,l,r,1); else if(op=='I') fill(1,0,l-1,0),fill(1,r+1,n,0); else if(op=='D') fill(1,l,r,0); else if(op=='C') fill(1,0,l-1,0),fill(1,r+1,n,0),rev(1,l,r); else rev(1,l,r); } dfs(1); if(SZ(V)==0) { puts("empty set"); return 0; } int i; int tot=SZ(V); for(i=0;i<tot-1;i++) { if(V[i].second+1==V[i+1].first) V[i+1].first=V[i].first; else { if(V[i].first&1) putchar('('); else putchar('['); printf("%d,%d",V[i].first>>1,V[i].second+1>>1); if(V[i].second&1) putchar(')'); else putchar(']'); putchar(' '); } } if(V[i].first&1) putchar('('); else putchar('['); printf("%d,%d",V[i].first>>1,V[i].second+1>>1); if(V[i].second&1) putchar(')'); else putchar(']'); putchar(' '); puts(""); }