HDU 3487 Play with Chain(区间FLIP、CUT)
2013-01-23 13:46
162 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3487
题意:一个数列两种操作:(1)将一个区间翻转;(2)将一个区间剪下放到另一个位置。
思路:翻转区间[A,B],将A-1,B+1分别调整到根和根节点的右子树;则[A,B]被调整到根节点右子树的左子树,记录翻转标记;剪切时第一步跟翻转一样,第二部将根节点右子树的左子树P剪下,设新插入的位置为C,将C和C+1分别调整到根和根节点的右子树,此时根节点的右子树的左子树为空,将P插在该位置。
题意:一个数列两种操作:(1)将一个区间翻转;(2)将一个区间剪下放到另一个位置。
思路:翻转区间[A,B],将A-1,B+1分别调整到根和根节点的右子树;则[A,B]被调整到根节点右子树的左子树,记录翻转标记;剪切时第一步跟翻转一样,第二部将根节点右子树的左子树P剪下,设新插入的位置为C,将C和C+1分别调整到根和根节点的右子树,此时根节点的右子树的左子树为空,将P插在该位置。
int n,m; int c [2],p ,s ,sign ; int root; void update(int f,int x,int flag) { p[x]=f; if(!f) return; c[f][flag]=x; s[f]=1+s[c[f][0]]+s[c[f][1]]; } void down(int x) { if(!sign[x]) return; sign[x]=0; swap(c[x][0],c[x][1]); sign[c[x][0]]^=1; sign[c[x][1]]^=1; } void rotate(int x) { int P=p[x],G=p[P]; if(c[P][0]==x) { update(P,c[x][1],0); update(x,P,1); update(G,x,!(c[G][0]==P)); } else { update(P,c[x][0],1); update(x,P,0); update(G,x,!(c[G][0]==P)); } } void splay(int x,int &goal) { int P=p[x],G=p[P],limit=p[goal]; while(P!=limit) { if(G!=limit&&(c[G][0]==P)==(c[P][0]==x)) rotate(P); rotate(x); P=p[x]; G=p[P]; } goal=x; down(goal); } int select(int x) { int t=root; while(1) { down(t); if(s[c[t][0]]+1==x) break; if(s[c[t][0]]+1>x) t=c[t][0]; else x-=s[c[t][0]]+1,t=c[t][1]; } return t; } int build(int L,int R) { if(L>R) return 0; int m=(L+R)>>1; update(m,build(L,m-1),0); update(m,build(m+1,R),1); return m; } int main() { while(scanf("%d%d",&n,&m),n>=0&&m>=0) { memset(sign,0,sizeof(sign)); memset(s,0,sizeof(s)); memset(p,0,sizeof(p)); memset(c,0,sizeof(c)); root=build(1,n+2); int A,B,C,i,r1,r2; char op[10]; while(m--) { scanf("%s",op); if(op[0]=='C') { scanf("%d%d%d",&A,&B,&C); r1=select(A); r2=select(B+2); splay(r1,root); splay(r2,c[root][1]); i=c[c[root][1]][0]; c[c[root][1]][0]=0; update(c[root][1],0,0); update(root,c[root][1],1); r1=select(C+1); r2=select(C+2); splay(r1,root); splay(r2,c[root][1]); c[c[root][1]][0]=i; update(c[root][1],i,0); update(root,c[root][1],1); } else { scanf("%d%d",&A,&B); r1=select(A); r2=select(B+2); splay(r1,root); splay(r2,c[r1][1]); i=c[root][1]; i=c[i][0]; sign[i]^=1; } } for(i=2;i<n+1;i++) printf("%d ",select(i)-1); printf("%d\n",select(i)-1); } return 0; }
相关文章推荐
- hdu 3487 Play with Chain splay 区间翻转,插入,删除
- HDU-3487 Play with Chain Splay tee区间反转,移动
- hdu 3487 Play with Chain (Splay树) 区间切割 插入 翻转
- hdu-3487-Play with Chain-(splay 区间翻转,切割,插入)
- Splay树(区间添加删除 | 区间翻转)——HDU 3487 Play with Chain
- HDU 3487 Play with Chain (Splay tree)区间切割和反转操作。
- hdu 3487 Play with Chain(splay区间剪切,翻转)
- Play with Chain HDU - 3487 splay区间翻转,区间位移
- HDU-3487 Play with Chain (splay好题 带翻转 cut-link操作)
- hdu 3487 Play with Chain (Splay tree基础)
- 【HDU】3487 Play with Chain Splay
- HDU 3487 Play with Chain 伸展树splay
- hdu 3487 Play with Chain splay tree
- hdu 3487 Play with Chain
- HDU 3487 Play with Chain (Splay tree)
- hdu 3487 Play with Chain(splay)
- 【HDU】3487 Play with Chain
- HDU 3487——Play with Chain(splay tree)
- Splay 模板题 一 hdu 3487 play with chain
- hdu 3487 Play with Chain (Splay Tree easy)