HDU_3487
题意:给出n和q,n代表1-n的序列,接下来q有两种操作,Cut a b c:表示把区间[a,b]截掉然后放在第c个数的后面,Flip a b 表示把区间[a,b]反转,经过一系列的q操作,最后输出操作后的序列:
分析:首先建立初始化的树结构之前,先给n设置个极限范围0和n+1,防止特殊情况下越界,如果反转[a,b],则先把第a-1个数放在根节点,把b+1结点的数放在根节点的右儿子下面,此时根节点的右儿子的左儿子为根的子树就是[a,b]区间,然后把反转标记传递给该子树的根节点,如果剪切区间[a,b]则把第c+1个数旋转到根节点处,然后把根节点的右儿子为子树的最左面的节点旋转到该子树的根,此时把剪掉的子树的根节点连到根节点的右儿子的左儿子上面即可,需要注意的是,push_down和push_up的操作
codes:指针
#include"stdio.h" #include"iostream" #include"queue" using namespace std; struct Link_cut { queue<int>q; struct node //节点结构体 { int key,val,son,flag; node *lson,*rson,*fa; //左儿子,右儿子,以及父节点 node() { key=val=flag=0; son=1; lson=rson=fa=NULL; } }; node *top,*root,*x,*y; void init() //建立根节点root的父节点top { top=new node(); } int getNum(node *x) //以x为根的子树一共有多少个节点 { if(x==NULL)return 0; return x->son; } void push_up(node *rt) { rt->son=getNum(rt->lson)+getNum(rt->rson)+1; } void push_down(node *rt) { if(rt==NULL)return; if(rt->flag) { rt->flag^=1; Reversal(rt); if(rt->lson!=NULL) rt->lson->flag^=1; if(rt->rson!=NULL) rt->rson->flag^=1; } } void Rotate(node *x,int k) //k=0左旋k=1右旋 { node *y=x->fa; if(k==0) { y->rson=x->lson; if(y->rson!=NULL) y->rson->fa=y; push_up(y); if(y->fa->rson==y) y->fa->rson=x; else y->fa->lson=x; x->fa=y->fa; x->lson=y; y->fa=x; } else { y->lson=x->rson; if(y->lson!=NULL) y->lson->fa=y; push_up(y); if(y->fa->lson==y) y->fa->lson=x; else y->fa->rson=x; x->fa=y->fa; x->rson=y; y->fa=x; } } void Splay(node *x,node *f)//把x旋转到f的下面 { while(x->fa!=f) { node *y=x->fa; node *z=y->fa; if(z==f) { if(y->rson==x) Rotate(x,0); else Rotate(x,1); } else { if(z->rson==y) { if(y->rson==x) { Rotate(y,0); Rotate(x,0); } else { Rotate(x,1); Rotate(x,0); } } else { if(y->lson==x) { Rotate(y,1); Rotate(x,1); } else { Rotate(x,0); Rotate(x,1); } } } } if(f==top) root=x; } void RotateTo(node *x,node *f) { Splay(x,f); push_up(x); } void RotateTo(int k,node *f) { node *x=root; k++; while(1) { push_down(x); int temp=getNum(x->lson)+1; if(k==temp)break; if(k<temp) x=x->lson; else { k-=temp; x=x->rson; } } Splay(x,f); push_up(x); } void creatTree(int l,int r,int k,node *f) //初始化一颗二叉树 { if(l>r)return; int mid=(l+r)/2; node *rt=new node(); if(f==top) root=rt; if(k==0) { f->lson=rt; rt->fa=f; rt->key=mid; } else { f->rson=rt; rt->fa=f; rt->key=mid; } creatTree(l,mid-1,0,rt); creatTree(mid+1,r,1,rt); push_up(rt); } void Reversal(node *x)//交换x左右儿子的结点 { if(x==NULL)return; node *y=x->lson; x->lson=x->rson; x->rson=y; } node *Find(int k) //找到第k的结点 { node *x=root; k++; while(1) { push_down(x); int temp=getNum(x->lson)+1; if(k==temp)break; else if(k<temp) x=x->lson; else { k-=temp; x=x->rson; } } return x; } node *FindRight(node *rt) //找到以rt为根节点的最右一个结点 { node *x=rt; while(1) { push_down(x); if(x->rson==NULL) break; x=x->rson; } return x; } node *FindLeft(node *rt) //找到以rt为根节点的最左一个结点 { node *x=rt; while(1) { push_down(x); if(x->lson==NULL)break; x=x->lson; } return x; } void Link(node *rt,int k) //把rt为根的子树连接到第k个结点的后面 { root->rson->lson=NULL; //把区间砍掉 node *x=Find(k); RotateTo(x,top); node *y=FindLeft(root->rson); RotateTo(y,root); root->rson->lson=rt; rt->fa=root->rson; } void Output(node *x,int n) { if(x==NULL)return; push_down(x); Output(x->lson,n); if(x->key>=1&&x->key<=n) q.push(x->key); Output(x->rson,n); } }h; int main() { int n,q; while(scanf("%d%d",&n,&q)!=-1) { if(n==-1&&q==-1)break; h.init(); h.creatTree(0,n+1,0,h.top); char op[11]; int a,b,c; while(q--) { scanf("%s%d%d",op,&a,&b); if(op[0]=='C') { scanf("%d",&c); h.RotateTo(a-1,h.top); h.RotateTo(b+1,h.root); h.Link(h.root->rson->lson,c); } else { h.RotateTo(a-1,h.top); h.RotateTo(b+1,h.root); h.root->rson->lson->flag^=1; } } while(!h.q.empty()) { h.q.pop(); } h.Output(h.root,n); printf("%d",h.q.front()); h.q.pop(); while(!h.q.empty()) { printf(" %d",h.q.front()); h.q.pop(); } puts(""); } } /* 8 1 CUT 3 5 4 5 1 CUT 2 3 1 8 3 Cut 3 6 3 Cut 2 6 2 Cut 3 6 4 8 1 Flip 2 6 10 5 Cut 2 6 3 Flip 4 9 Flip 5 8 Cut 6 7 3 Flip 4 5 */
codes:数组模拟
#include"stdio.h" #include"iostream" #include"queue" #include"string.h" #define M 3000005 using namespace std; struct Text { int son[M][2],fa[M],flip[M],num[M]; int top; int root; vector<int>p; void init(int n) { top=n+2; for(int i=0;i<=n+2;i++) { num[i]=1; flip[i]=0; son[i][0]=son[i][1]=-1; fa[i]=-1; } } void Rotate(int x,int k) { int y=fa[x]; if(k==0) { son[y][1]=son[x][0]; if(son[y][1]!=-1) fa[son[y][1]]=y; push_up(y); if(son[fa[y]][0]==y) son[fa[y]][0]=x; else son[fa[y]][1]=x; fa[x]=fa[y]; son[x][0]=y; fa[y]=x; } else { son[y][0]=son[x][1]; if(son[y][0]!=-1) fa[son[y][0]]=y; push_up(y); if(son[fa[y]][0]==y) son[fa[y]][0]=x; else son[fa[y]][1]=x; fa[x]=fa[y]; son[x][1]=y; fa[y]=x; } } int Find(int k) { k++; int x=root; while(1) { push_down(x); int temp=getNum(son[x][0])+1; if(temp==k)break; else if(k<temp) x=son[x][0]; else { k-=temp; x=son[x][1]; } } return x; } void splay(int x,int f) { if(x==-1)return; while(fa[x]!=f) { int y=fa[x]; int z=fa[y]; if(z==f) { if(son[y][0]==x) Rotate(x,1); else Rotate(x,0); } else { if(son[z][0]==y) { if(son[y][0]==x) { Rotate(y,1); Rotate(x,1); } else { Rotate(x,0); Rotate(x,1); } } else { if(son[y][1]==x) { Rotate(y,0); Rotate(x,0); } else { Rotate(x,1); Rotate(x,0); } } } } if(f==top) root=x; } void RotateTo(int x,int f,int type) { if(!type) x=Find(x); splay(x,f); push_up(x); } void Reversal(int x) { if(x==-1)return; int y=son[x][0]; son[x][0]=son[x][1]; son[x][1]=y; } void creat(int l,int r,int k,int f) { if(l>r)return; int mid=(l+r)/2; if(f==top) root=mid; son[f][k]=mid; fa[mid]=f; creat(l,mid-1,0,mid); creat(mid+1,r,1,mid); push_up(mid); } int getNum(int x) { if(x==-1)return 0; return num[x]; } void push_up(int rt) { num[rt]=getNum(son[rt][0])+getNum(son[rt][1])+1; } void push_down(int rt) { if(rt==-1)return; if(flip[rt]) { flip[rt]^=1; Reversal(rt); if(son[rt][0]!=-1) flip[son[rt][0]]^=1; if(son[rt][1]!=-1) flip[son[rt][1]]^=1; } } int findLeft(int rt) { int x=rt; while(1) { push_down(x); if(son[x][0]==-1)break; x=son[x][0]; } return x; } void CUT(int a,int b,int c) { RotateTo(a-1,top,0); RotateTo(b+1,root,0); int rt=son[son[root][1]][0]; son[son[root][1]][0]=-1; RotateTo(c,top,0); int x=findLeft(son[root][1]); RotateTo(x,root,1); son[son[root][1]][0]=rt; fa[rt]=son[root][1]; } void FLIP(int a,int b) { RotateTo(a-1,top,0); RotateTo(b+1,root,0); int x=son[son[root][1]][0]; flip[x]^=1; } void dfs(int rt,int n) { if(rt==-1)return; push_down(rt); dfs(son[rt][0],n); if(rt>=1&&rt<=n) p.push_back(rt); dfs(son[rt][1],n); } void Output(int n) { dfs(root,n); printf("%d",p[0]); for(int i=1;i<(int)p.size();i++) printf(" %d",p[i]); puts(""); p.clear(); } }text; int main() { int n,q; while(scanf("%d%d",&n,&q)!=-1) { if(n==q&&n==-1)break; text.init(n); text.creat(0,n+1,0,text.top); int a,b,c; char op[10]; while(q--) { scanf("%s%d%d",op,&a,&b); if(op[0]=='C') { scanf("%d",&c); text.CUT(a,b,c); } else text.FLIP(a,b); } text.Output(n); } return 0; } /* 10 5 Cut 2 6 3 Flip 4 9 Flip 5 8 Cut 6 7 3 Flip 4 5 10 5 Flip 4 9 Flip 5 8 Cut 6 7 3 Flip 4 5 10 1 Flip 2 9 */