hdu 2475 box LCT

来源:互联网 发布:正态分布的随机矩阵 编辑:程序博客网 时间:2024/04/27 22:28

题意是箱子套箱子,每次移动箱子x到箱子y里,或询问x最外层的箱子。
这一道题根是固定的,不能换根。

#include<iostream>#include<cstdio>#include<cstring>#define maxn 50005using namespace std;int fa[maxn],ch[maxn][2];int f[maxn];bool isroot(int x){return ch[fa[x]][0]!=x&&ch[fa[x]][1]!=x;}bool dir(int x){return ch[fa[x]][1]==x;}void rotate(int x){    int y=fa[x],z=fa[y];    bool b=dir(x);    int a=ch[x][!b];    if(!isroot(y))        ch[z][dir(y)]=x;    fa[x]=z;ch[x][!b]=y;    fa[y]=x;ch[y][b]=a;    if(a) fa[a]=y;}void splay(int x){    while(!isroot(x))    {        int y=fa[x];        if(isroot(y)) rotate(x);        else        {            bool b=dir(x),c=dir(y);            if(b^c) {rotate(y);rotate(x);}            else    {rotate(x);rotate(x);}        }    }}void access(int x){    for(int t=0;x;t=x,x=fa[x])        splay(x),ch[x][1]=t;}int find_root(int x){    access(x);splay(x);    while(ch[x][0]) x=ch[x][0];    return x;}void cut(int x){    access(f[x]);    splay(x);fa[x]=0;}void link(int x,int y){    cut(x);    if(!y)return ;    if(find_root(y)==x)    {        splay(x);        fa[x]=f[x];        return ;    }    fa[x]=y;    f[x]=y;}char s[10];void init(){    memset(f,0,sizeof(f));    memset(fa,0,sizeof(fa));    memset(ch,0,sizeof(ch));}int main(){    int n;    bool fst=1;    while(scanf("%d",&n)!=EOF)    {        if(fst) fst=0;        else puts("");        init();        for(int i=1;i<=n;i++)        {            scanf("%d",&fa[i]);            f[i]=fa[i];        }        int m,x,y;        scanf("%d",&m);        for(int i=1;i<=m;i++)        {            scanf("%s%d",s,&x);            if(s[0]=='Q')                printf("%d\n",find_root(x));            else            {                scanf("%d",&y);                link(x,y);            }        }    }    return 0;}
1 0
原创粉丝点击