HDU 2475 Box(splay)
2013-03-28 21:32
429 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2475
题意:给出一棵树,两种操作:(1)修改某棵子树的父节点;(2)查询某个节点的根节点。
思路:每个题目中的箱子看做两个箱子i和i+n,(i,i+n)之间的为在i箱子中的。对于第一种操作,比如将u的父节点改为v,首先将u转到根节点,然后将u+n根节点右孩子,然后u子树就可以被整体切下。然后将另外两部分连接在一起。然后将v转到根,将v之后最左的节点转到v右孩子,然后将u插入v右孩子的左孩子。查询直接将u转到根,找到最左孩子。
题意:给出一棵树,两种操作:(1)修改某棵子树的父节点;(2)查询某个节点的根节点。
思路:每个题目中的箱子看做两个箱子i和i+n,(i,i+n)之间的为在i箱子中的。对于第一种操作,比如将u的父节点改为v,首先将u转到根节点,然后将u+n根节点右孩子,然后u子树就可以被整体切下。然后将另外两部分连接在一起。然后将v转到根,将v之后最左的节点转到v右孩子,然后将u插入v右孩子的左孩子。查询直接将u转到根,找到最左孩子。
struct node { int id; node *c[2],*f; }; node a ,*nullNode; int n,m; void rotate(node *x,int k) { node *y=x->f; y->c[k]=x->c[!k]; y->c[k]->f=y; x->f=y->f; if(y->f->c[0]==y) y->f->c[0]=x; else y->f->c[1]=x; y->f=x; x->c[!k]=y; } void splay(node *x,node *y) { while(x->f!=y) { if(x->f->f==y) { if(x->f->c[0]==x) rotate(x,0); else rotate(x,1); } else if(x->f->f->c[0]==x->f) { if(x->f->c[0]==x) rotate(x->f,0); else rotate(x,1); rotate(x,0); } else { if(x->f->c[1]==x) rotate(x->f,1); else rotate(x,0); rotate(x,1); } } } void change(int u,int v) { if(u==v) return; splay(a+u,nullNode); splay(a+u+n,a+u); node *p; if(v!=0) { p=a+v; while(p!=nullNode) { if(p==a[u+n].c[0]) return; p=p->f; } } node *x=a[u].c[0],*y=a[u+n].c[1]; a[u].c[0]=nullNode; a[u+n].c[1]=nullNode; x->f=y->f=nullNode; if(x!=nullNode&&y!=nullNode) { while(y->c[0]!=nullNode) y=y->c[0]; y->c[0]=x; x->f=y; } if(v==0) return; splay(a+v,nullNode); p=a[v].c[1]; while(p->c[0]!=nullNode) p=p->c[0]; splay(p,a+v); p->c[0]=a+u; a[u].f=p; } int query(int x) { splay(a+x,nullNode); node *p=a+x; while(p->c[0]!=nullNode) p=p->c[0]; return p->id; } int get() { int x=0,flag=1; char c=getchar(); while(!isdigit(c)) c=getchar(); if(c=='-') { flag=-1,c=getchar(); while(!isdigit(c)) c=getchar(); } while(isdigit(c)) { x=x*10+c-'0'; c=getchar(); } return x*flag; } vector<int> g ; int isRoot ; node *build(int u) { node *pre=a+u,*last=a+u,*cur; int i,v; FOR0(i,SZ(g[u])) { v=g[u][i]; last=build(v); pre->c[1]=a+v; a[v].f=pre; pre=last; } cur=a+u+n; last->c[1]=cur; cur->f=last; return a+u+n; } void init() { nullNode=new node(); nullNode->c[0]=nullNode->c[1]=nullNode->f=nullNode; int i,u; FOR1(i,n) g[i].clear(); clr(isRoot,0); FOR1(i,(n+n)) { a[i].c[0]=a[i].c[1]=a[i].f=nullNode; a[i].id=i; } FOR1(i,n) { u=get(); if(u==0) isRoot[i]=1; else g[u].pb(i); } node *p; FOR1(i,n) if(isRoot[i]) { build(i); a[i].f=nullNode; } } int main() { bool flag=false; while(scanf("%d",&n)!=-1) { if(flag) puts(""); else flag=true; init(); int u,v; m=get(); char op[10]; while(m--) { scanf("%s",op); if(op[0]=='M') { u=get(),v=get(); change(u,v); } else u=get(),PR(query(u)); } } return 0; }
相关文章推荐
- hdu-2475-Box-splay
- 【HDU】2475 Box
- HDU 2475 BOX 动态树 Link-Cut Tree
- HDU 2475 Box
- hdu 2475 Box(伸展树)
- HDU 2475 Box 树型转线型 + 伸展树
- HDU 2475 Box
- HDU 2475 Box [dfs序+splay]
- hdu1754(splay)
- hdu 3487 Play with Chain splay 区间翻转,插入,删除
- HDOJ(HDU) 2143 box(简单的多次判断-用的卫条件)
- HDU-3487 Play with Chain Splay tee区间反转,移动
- hdu 5155 Harry And Magic Box BC#25比赛1002
- hdu1890 Robotic Sort (splay+区间翻转单点更新)
- hdu 3487 Play with Chain (Splay Tree easy)
- 水题 ~ HDU 1326 Box of Bricks
- HDU-3487 Play with Chain (splay好题 带翻转 cut-link操作)
- HDU 1754 I Hate It (Splay 区间操作)
- Play with Chain HDU - 3487 splay区间翻转,区间位移
- HDU 2143 BOX (水题)