大体说一下思路:将开区间和闭区间拆成两个点,用线段树或者平衡树(论练代(Do)码(Die)的重要性……)来维护01串就好。
40分代码,实在懒得调了QAQ
const int MAXN=65536*2; typedef struct NODE{ int l,r; bool inv,same,v; NODE *lchild,*rchild; NODE(){} NODE(int _l,int _r):l(_l),r(_r),v(0),inv(0),same(0){} } *TREE; TREE root; char order[6+2]; bool flag; int read(){ int x=0,f=0; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='(')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } if(ch==')') f=1; return x*2-f; } void Pushdown(TREE &x){ if(x->l==x->r){ x->v^=1; return; } if(x->same){ x->lchild->v=x->rchild->v=x->v; x->lchild->inv=x->rchild->inv=0; x->lchild->same=x->rchild->same=1,x->same=0; } x->lchild->inv^=x->inv,x->rchild->inv^=x->inv; } void Build(TREE &x,int l,int r){ x=new NODE(l,r); if(l==r) return; int m=(l+r)>>1; Build(x->lchild,l,m),Build(x->rchild,m+1,r); } void Change(TREE &x,int l,int r,bool v){ if(l>r) return; if(x->l>=l && x->r<=r){ x->same=1,x->v=v,x->inv=0; return; } Pushdown(x); int m=(x->l+x->r)>>1; if(l<=m) Change(x->lchild,l,r,v); if(r>m) Change(x->rchild,l,r,v); } void Inverse(TREE &x,int l,int r){ if(l>r) return; if(x->l>=l && x->r<=r){ x->inv^=1,x->v^=1; return; } Pushdown(x); int m=(x->l+x->r)>>1; if(l<=m) Inverse(x->lchild,l,r); if(r>m) Inverse(x->rchild,l,r); } bool Query(TREE &x,int p){ if(x->l==x->r) return x->v; Pushdown(x); int m=(x->l+x->r)>>1; if(p<=m) return Query(x->lchild,p); return Query(x->rchild,p); } int main(){ Build(root,1,MAXN); int a,b; while(scanf("%s",order)!=EOF){ a=read(),b=read(); a+=2,b+=2; if(order[0]=='U') Change(root,a,b,1); if(order[0]=='I') Change(root,1,a-1,0),Change(root,b+1,MAXN,0); if(order[0]=='D') Change(root,a,b,0); if(order[0]=='C') Change(root,1,a-1,0),Change(root,b+1,MAXN,0),Inverse(root,a,b); if(order[0]=='S') Inverse(root,a,b); } for(int i=1,s=-1,t=-1;i<=MAXN;i++) if(Query(root,i)){ if(s==-1) s=i; t=i; } else{ if(s!=-1){ if(s&1) printf("("); else printf("["); cout << (s>>1)-1 << "," << ((t+1)>>1)-1; if(t&1) printf(") "); else printf("] "); } s=t=-1; } return 0; }平衡树代码……Select在处理0边界的时候死活调不出来了,希望哪位神犇能讲一下……
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int MAXN=65536*2; typedef struct NODE{ int c; bool v,same,inv; NODE *child[2],*f; } *TREE; TREE root,Null; char order[6+2]; bool flag; int read(){ int x=0,f=0; char ch=getchar(); while(ch<'0'||ch>'9'){ if(ch=='(')f=-1; ch=getchar(); } while(ch>='0'&&ch<='9'){ x=x*10+ch-'0'; ch=getchar(); } if(ch==')') f=1; return x*2-f; } TREE NewNode(TREE f){ TREE x=new NODE; x->f=f,x->child[0]=x->child[1]=Null; x->c=1,x->v=x->same=x->inv=0; return x; } void Initialization(){ Null=NewNode(0),Null->c=0; root=NewNode(Null); root->child[1]=NewNode(root); } void Pushup(TREE x){ if(x==Null) return; x->c=x->child[0]->c+x->child[1]->c+1; } void Pushdown(TREE x){ if(x==Null) return; if(x->same){ x->child[0]->same=x->child[1]->same=1; x->child[0]->v=x->child[1]->v=x->v; x->child[0]->inv=x->child[1]->inv=0; x->same=0; } if(x->inv){ x->child[0]->inv^=1,x->child[1]->inv^=1; x->inv=0,x->v^=1; } } void Rotate(TREE x,bool t){ TREE y=x->f; Pushdown(x->child[0]),Pushdown(x->child[1]),Pushdown(y->child[t]); y->child[!t]=x->child[t],x->child[t]->f=y,x->f=y->f; if(y->f->child[0]==y) y->f->child[0]=x; else y->f->child[1]=x; y->f=x,x->child[t]=y; Pushup(y),Pushup(x); if(y==root) root=x; } void Splay(TREE x,TREE y){ Pushdown(x); while(x->f!=y) if(x->f->f==y) if(x->f->child[0]==x) Rotate(x,1); else Rotate(x,0); else if(x->f->f->child[0]==x->f) if(x->f->child[0]==x) Rotate(x->f,1),Rotate(x,1); else Rotate(x,0),Rotate(x,1); else if(x->f->child[0]==x) Rotate(x,1),Rotate(x,0); else Rotate(x->f,0),Rotate(x,0); } void Select(int p,TREE y){ TREE x=root;Pushdown(x); while(p!=x->child[0]->c+1){ if(p<=x->child[0]->c) x=x->child[0]; else p-=x->child[0]->c+1,x=x->child[1]; Pushdown(x); } Splay(x,y); } void Build(int p,int n){ TREE s,t; s=t=NewNode(Null); for(int i=2;i<=n;i++) t=t->child[1]=NewNode(t); Select(p+1,Null),Select(p+2,root); root->child[1]->child[0]=s,s->f=root->child[1]; Splay(t,Null); } void Change(int p,int n,bool v){ Select(p-1,Null),Select(p+n,root); root->child[1]->child[0]->v=v; root->child[1]->child[0]->inv=0; root->child[1]->child[0]->same=1; Splay(root->child[1]->child[0],Null); } void Inverse(int p,int n){ Select(p-1,Null),Select(p+n,root); root->child[1]->child[0]->inv^=1; Splay(root->child[1]->child[0],Null); } bool Query(int p){ TREE x=root;Pushdown(x); while(p!=x->child[0]->c+1){ if(p<=x->child[0]->c) x=x->child[0]; else p-=x->child[0]->c+1,x=x->child[1]; Pushdown(x); } return x->v; } int main(){ Initialization(); Build(0,MAXN); int a,b; while(scanf("%s",order)!=EOF){ a=read(),b=read(); a+=2,b+=2; if(order[0]=='U') Change(a,b-a+1,1); if(order[0]=='I') Change(b+1,MAXN-b,0); if(order[0]=='D') Change(a,b-a+1,0); if(order[0]=='C') Change(1,a-1,0),Change(b+1,MAXN-b,0),Inverse(a,b-a+1); if(order[0]=='S') Inverse(a,b-a+1); } int s=-1,t=-1; for(int i=1;i<=MAXN;i++){ if(Query(i)){ if(s==-1) s=i; t=i; } else{ if(s!=-1){ if(s&1) cout << "("; else cout << "["; cout << (s>>1)-1 << "," << ((t+1)>>1)-1; if(t&1) cout << ") "; else cout << "] "; } t=s=-1,flag=1; } } if(!flag) cout << "empty set" << endl; return 0; }