您的位置:首页 > 其它

HDU 2475 BOX 动态树 Link-Cut Tree

2015-04-25 12:59 337 查看

Box

Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

[align=left]【Problem Description】[/align]
There are N boxes on the ground, which are labeled by numbers from 1 to N. The boxes are magical, the size of each one can be enlarged or reduced arbitrarily. Jack can perform the “MOVE x y” operation to the boxes: take out box x; if y = 0, put it on the ground; Otherwise, put it inside box y. All the boxes inside box x remain the same. It is possible that an operation is illegal, that is, if box y is contained (directly or indirectly) by box x, or if y is equal to x. In the following picture, box 2 and 4 are directly inside box 6, box 3 is directly inside box 4, box 5 is directly inside box 1, box 1 and 6 are on the ground.

/* ***********************************************
MYID    : Chen Fan
LANG    : G++
PROG    : HDU 2475
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

#define MAXN 50010

int sons[MAXN][2];
int father[MAXN],pathfather[MAXN],data[MAXN];
bool root[MAXN];
int spttail=0;

void rotate(int x,int w) //rotate(node,0/1)
{
int y=father[x];

sons[y][!w]=sons[x][w];
if (sons[x][w]) father[sons[x][w]]=y;
father[x]=father[y];
if (father[y]&&(!root[y])) sons[father[y]][y==sons[father[y]][1]]=x;
sons[x][w]=y;
father[y]=x;

if (root[y])
{
root[x]=true;
root[y]=false;
}
}

void splay(int x) //splay(node)
{
while(!root[x])
{
if (root[father[x]]) rotate(x,x==sons[father[x]][0]);
else
{
int t=father[x];
int w=(sons[father[t]][0]==t);
if (sons[t][w]==x)
{
rotate(x,!w);
rotate(x,w);
} else
{
rotate(t,w);
rotate(x,w);
}
}
}
}

void access(int v)
{
int u=v;
v=0;
while(u)
{
splay(u);
root[sons[u][1]]=true;
sons[u][1]=v;
root[v]=false;
v=u;
u=father[u];
}
}

int findroot(int v)
{
access(v);
splay(v);
while (sons[v][0]) v=sons[v][0];
//splay(v,0);
return v;
}

void cut(int v)
{
access(v);
splay(v);
father[sons[v][0]]=0;
root[sons[v][0]]=true;
sons[v][0]=0;
}

void join(int v,int w)
{
if (!w) cut(v);
else
{
access(w);
splay(w);
int temp=v;
while(!root[temp]) temp=father[temp];
if (temp!=w)
{
cut(v);
father[v]=w;
}
}
}

int INT()
{
char ch;
int res;
while (ch=getchar(),!isdigit(ch));
for (res = ch - '0';ch = getchar(),isdigit(ch);)
res = res * 10 + ch - '0';
return res;
}

char CHAR()
{
char ch, res;
while (res = getchar(), !isalpha(res));
while (ch = getchar(), isalpha(ch));
return res;
}

int main()
{
//freopen("2475.txt","r",stdin);

int n;
double flag=false;
while(scanf("%d",&n)!=EOF)
{
if (flag) printf("\n");
flag=true;

memset(father,0,sizeof(father));
memset(sons,0,sizeof(sons));
for (int i=1;i<=n;i++)
{
//scanf("%d",&father[i]);
father[i]=INT();
root[i]=true;
}

int m;
m=INT();
for (int i=1;i<=m;i++)
{
char s=CHAR();
if (s=='M')
{
int x,y;
x=INT();
y=INT();
join(x,y);
} else
{
int q;
q=INT();
printf("%d\n",findroot(q));
}
}
}

return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: