hdu2475 Box splay || 动态树
来源:互联网 发布:mac系统PPT怎么转换 编辑:程序博客网 时间:2024/05/19 00:15
题意:一开始给定n个盒子的摆的嵌套关系。有两种操作,1.MOVE x y:把编号x的箱子及其包含的箱子放进编号为y的箱子;
2.QUERY x :查询编号x的箱子所在的最靠外的箱子。
方法一:splay+括号序
思路:将全部的树逐个dfs,这样对于每一棵树都可以得到一个括号序列,对于MOVE操作,我们将那个根所在的左右括号的一整段
取出,连接到新的结点的左括号右边,这么做我们可以保证得到的一定也是一个括号序列。我们将x和x+n分别旋根,这样我们可以得到一个x和x+n,x+n是根,x是其左子树的某一个结点,这样x的左子树和x+n的右子树是无效的,我们剪掉它们,并且将x+n的右子树接到x的左子树最后,接着把x+n旋根,保证平衡性。对于QUERY操作,我们直接去找其结点所在的括号序列靠最左边的是谁就可以了。详见代码:
/********************************************************* file name: hdu2475.cpp author : kereo create time: 2015年02月18日 星期三 14时29分43秒*********************************************************/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int sigma_size=26;const int N=100+50;const int MAXN=100000+50;const int inf=0x3fffffff;const double eps=1e-8;const int mod=1000000000+7;#define L(x) (x->ch[0])#define R(x) (x->ch[1])#define PII pair<int, int>#define mk(x,y) make_pair((x),(y))int n,m,edge_cnt,cnt;char str[N];int head[MAXN],seq[MAXN],vis[MAXN];struct Edge{ int v,next;}edge[MAXN];struct node{ node *fa,*ch[2];}nod[MAXN],*root,*null;struct Splay{ void rotate(node *x,int d){ node *y=x->fa; //push_down(y); push_down(x); y->ch[d^1]=x->ch[d]; if(x->ch[d]!=null) x->ch[d]->fa=y; x->fa=y->fa; if(y->fa!=null){ int d=y->fa->ch[0] == y ? 0 : 1; y->fa->ch[d]=x; } y->fa=x; x->ch[d]=y; //push_up(y); } void splay(node *x,node *fa){ while(x->fa!=fa){ //push_down(x); node *y=x->fa; if(y->fa == fa){ int d=y->ch[0] == x ? 1 : 0; rotate(x,d); } else{ int d=y->fa->ch[0] == y ? 1 : 0; if(y->ch[d] == x){ rotate(x,d^1); rotate(x,d); } else{ rotate(y,d); rotate(x,d); } } } //push_up(x); if(fa == null) root=x; } void newnode(node *&x,node *fa,int pos){ x=&nod[pos]; x->fa=fa; L(x)=R(x)=null; } void build(node *&rt,node *fa,int l,int r){ if(l>r) return ; int mid=(l+r)>>1; newnode(rt,fa,seq[mid]); build(L(rt),rt,l,mid-1); build(R(rt),rt,mid+1,r); //push_up(rt); } void init(){ null=&nod[0]; root=null; L(null)=R(null)=null->fa=null; } void MOVE(int x,int y){ if(x == y) return ; splay(&nod[x],null); splay(&nod[x+n],&nod[x]); node *tmp; for(tmp=&nod[y];tmp!=null;tmp=tmp->fa){ if((&nod[x+n])->ch[0] == tmp) return ; } node *pre=(&nod[x])->ch[0],*suf=(&nod[x+n])->ch[1]; (&nod[x])->ch[0]=(&nod[x+n])->ch[1]=pre->fa=suf->fa=null; if(pre!=null && suf!=null){ while(L(suf)!=null) suf=L(suf); pre->fa=suf; L(suf)=pre; } if(y == 0) return ; splay(&nod[y],null); for(tmp=(&nod[y])->ch[1];L(tmp)!=null;tmp=L(tmp)) ; splay(tmp,&nod[y]); L(tmp)=&nod[x]; (&nod[x])->fa=tmp; } int QUERY(int x){ node *tmp=&nod[x]; splay(tmp,null); for(;L(tmp)!=null;tmp=L(tmp)) ; return tmp-nod; }}spt;void init(){ edge_cnt=0; memset(vis,0,sizeof(vis)); memset(head,-1,sizeof(head));}void addedge(int u,int v){ edge[edge_cnt].v=v; edge[edge_cnt].next=head[u]; head[u]=edge_cnt++;}void dfs(int u){ seq[++cnt]=u; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; dfs(v); } seq[++cnt]=u+n;}int main(){ int flag=1; //freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ init(); spt.init(); if(flag) flag=0; else printf("\n"); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); if(x == 0) vis[i]=1; else addedge(x,i); } for(int i=1;i<=n;i++){ if(!vis[i]) continue; cnt=0; dfs(i); spt.build(root,null,1,cnt); } scanf("%d",&m); while(m--){ scanf("%s",str); if(strcmp(str,"MOVE") == 0){ int x,y; scanf("%d%d",&x,&y); spt.MOVE(x,y); } else if(strcmp(str,"QUERY") == 0){ int x; scanf("%d",&x); int ans=spt.QUERY(x); printf("%d\n",ans); } } }return 0;}
方法二:Link-Cut Tree
思路:参阅《QTREE的一些研究》。tip:注释掉的部分导致TLE的原因:y=x->fa,恰好根是y->fa,且x,y,y->fa为“一字型”,那么会先把根
转下去,那么更新x->par的时候就会出现问题。详见代码:
/********************************************************* file name: hdu2475.cpp author : kereo create time: 2015年02月21日 星期六 10时23分07秒*********************************************************/#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<set>#include<map>#include<vector>#include<stack>#include<cmath>#include<string>#include<algorithm>using namespace std;typedef long long ll;const int sigma_size=26;const int N=100+50;const int MAXN=100000+50;const int inf=0x3fffffff;const double eps=1e-8;const int mod=1000000000+7;#define L(x) (x->ch[0])#define R(x) (x->ch[1])#define PII pair<int, int>#define mk(x,y) make_pair((x),(y))int n,m;char str[N];struct node{ node *ch[2],*par,*fa;}nod[MAXN],*null,*root;struct LCT{ void rotate(node *x,int d){ node *y=x->fa; //push_down(y); push_down(x); y->ch[d^1]=x->ch[d]; x->ch[d]->fa=y; x->fa=y->fa; if(y->fa!=null){ int d=y->fa->ch[0] == y ? 0 : 1; y->fa->ch[d]=x; } y->fa=x; x->ch[d]=y; //push_up(y); } /*void splay(node *x,node *fa){ while(x->fa!=fa){ node *y=x->fa; if(y->fa == fa){ x->par=y->par; y->par=null; int d=y->ch[0] == x ? 1 : 0; rotate(x,d); } else{ int d=y->fa->ch[0] == y ? 1 : 0; if(y->ch[d] == x){ rotate(x,d^1); rotate(x,d); } else{ rotate(y,d); rotate(x,d); } } } if(fa == null) root=x; }*/ node* findroot(node *x){ while(x->fa!=null) x=x->fa; return x; } void splay(node *x,node *fa){ node *tmp=findroot(x); if(x == tmp) return ; x->par=tmp->par; tmp->par=null; while(x->fa!=fa){ node *y=x->fa; if(y->fa == fa){ int d=y->ch[0] == x ? 1 : 0; rotate(x,d); } else{ int d=y->fa->ch[0] == y ? 1 : 0; if(y->ch[d] == x){ rotate(x,d^1); rotate(x,d); } else{ rotate(y,d); rotate(x,d); } } } } void Access(node *x){ node *tmp=null; while(x!=null){ splay(x,null); if(R(x)!=null){ R(x)->fa=null; R(x)->par=x; } R(x)=tmp; if(tmp!=null){ tmp->fa=x; tmp->par=null; } tmp=x; x=x->par; } } void Cut(node *x){ Access(x); splay(x,null); if(L(x)!=null){ L(x)->par=x->par; x->par=null; L(x)->fa=null; L(x)=null; } } void Link(node *x,node *y){ if(y == null) Cut(x); else{ Access(y); splay(y,null); node *tmp=findroot(x); if(tmp == y) return ; Cut(x); x->par=y; Access(x); } } void init(){ null=&nod[0]; root=null; L(root)=R(root)=root->fa=null; } void newnode(node *&x,node *fa,node *par,int pos){ x=&nod[pos]; x->fa=fa; x->par=par; L(x)=R(x)=null; } int query(node *x){ Access(x); splay(x,null); while(L(x)!=null) x=L(x); return x-nod; }}lct;int main(){ int flag=1; //freopen("in.txt","r",stdin); while(~scanf("%d",&n)){ if(flag) flag=0; else printf("\n"); lct.init(); for(int i=1;i<=n;i++){ int x; scanf("%d",&x); lct.newnode(root,null,&nod[x],i); } //for(int i=1;i<=n;i++) // printf("i=%d par=%d fa=%d\n",i,(&nod[i])->par-nod,(&nod[i])->fa-nod); scanf("%d",&m); while(m--){ scanf("%s",str); if(strcmp(str,"MOVE") == 0){ int x,y; scanf("%d%d",&x,&y); lct.Link(&nod[x],&nod[y]); } else if(strcmp(str,"QUERY") == 0){ int x; scanf("%d",&x); int ans=lct.query(&nod[x]); printf("%d\n",ans); } } }return 0;}
0 0
- hdu2475 Box splay || 动态树
- hdu2475 BOX(splay+dfs序)
- hdu2475 Box
- 【hdu2475】Box
- hdu-2475-Box-splay
- SPOJ OTOCI <动态树 + splay>
- hdu 2475 Box (splay tree)
- hdu 2475 Box splay, lct
- hdu2475 LCT
- HDU 2475 Box [dfs序+splay]
- SPLAY树
- Splay树
- splay树
- splay树
- Splay 树
- splay树
- Splay树
- SPLAY树
- hdu3294---Girls' research
- IOS 自定义控件之UIAlertview
- Linux IPC实践(2) --匿名PIPE
- POJ1001 求高精度幂 ACM解题报告(高精度模板)
- linux下显示时间代码
- hdu2475 Box splay || 动态树
- Requirement Traceability Matrix (RTM) – What Is RTM And Why Do We Need It?
- Struts2 XML配置详解
- linux,unix,mac osx
- Linux的NAT即时生效问题
- 【BZOJ 2242】 [SDOI2011]计算器
- Linux IPC实践(3) --具名FIFO
- 割点割边连通分量等连通性相关算法
- Linux IPC实践(4) --System V消息队列(1)