題目描述:
1.a v 表示將v號堆棧複製一份,新棧的編號爲i,並將元素i壓入新棧的棧頂。
2. b v 表示將v號堆棧複製一份,新棧的編號爲i,將新棧的棧頂元素彈出。
3.c v w 將v號堆棧複製一份,編號爲i,並比較第v號和第w號堆棧中有多少相同的數。
輸入:
接下來n步,每步表示一個操作,如上所述。
輸出:
樣例輸入:
a 0
a 1
b 2
c 2 3
b 4
樣例輸出:
分析:
code:
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 300000
#define MAXD 20
using namespace std;
int fa[MAXN+5][MAXD+5],deep[MAXN+5];
int unit[MAXN+5],top[MAXN+5];
int n,d1,d2;
char o[2];
int find(int x){return unit[x]==x?x:unit[x]=find(unit[x]);}
void dfs(int u,int f)
{
int i;
fa[u][0]=f;
deep[u]=deep[f]+1;
for(i=1;i<=MAXD;i++)
{
if(deep[u]<(1<<i))
break;
fa[u][i]=fa[fa[u][i-1]][i-1];
}
}
int lca(int u,int v)
{
if(deep[u]<deep[v])
swap(u,v);
int i,t=deep[u]-deep[v];
for(i=0;i<=MAXD;i++)
if((1<<i)&t)
u=fa[u][i];
for(i=MAXD;i>=0;i--)
if(fa[u][i]!=fa[v][i])
{
u=fa[u][i];
v=fa[v][i];
}
if(u==v)
return u;
return fa[u][0];
}
int main()
{
int i;
scanf("%d",&n);
memset(fa,-1,sizeof fa);
for(i=1;i<=n;i++)
unit[i]=i;
for(i=1;i<=n;i++)
{
scanf("%s",o);
if(o[0]=='a')
{
scanf("%d",&d1);
d1=find(d1);
dfs(i,d1);
top[i]=i;
}
else if(o[0]=='b')
{
scanf("%d",&d1);
d1=find(d1);
int f=find(fa[d1][0]);
top[i]=top[f];
dfs(i,f);
unit[i]=f;
printf("%d\n",top[d1]);
}
else if(o[0]=='c')
{
scanf("%d%d",&d1,&d2);
d1=find(d1),d2=find(d2);
top[i]=top[d1];
int f1=find(fa[d1][0]),f2=find(d2);
dfs(i,f1);
unit[i]=d1;
int fi=find(i);
printf("%d\n",deep[lca(fi,f2)]);
}
}
}