Cod sursa(job #608096)

Utilizator Magnuscont cu nume gresit sau fals Magnus Data 14 august 2011 22:29:15
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.05 kb
#include <cstdio>

int n,m,a[100001],x,y,i,j,p[100001][20],l[100001];

int lca(int n,int p[100001][20],int a[100001],int l[100001],int x,int y)
{
    int i,t,lg;
    if(l[x]<l[y])
        t=x,x=y,y=t;
    for(lg=1;(1<<lg)<=l[x];lg++);
    --lg;
    for(i=lg;i>=0;--i)
        if(l[x]-(1<<i)>=l[y])
            x=p[x][i];
    if(x==y)
        return x;
    for(i=lg;i>=0;--i)
        if(p[x][i]!=-1&&p[x][i]!=p[y][i]&&p[y][i]!=-1)
            x=p[x][i],y=p[y][i];
    return a[x];
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d %d\n",&n,&m);
    l[1]=1;
    for(i=2;i<=n;++i)
    {
        scanf("%d\n",&a[i]);
        l[i]=l[a[i]]+1;
    }
    for(i=0;i<=n;++i)
    for(j=1;j<=18;++j)
        p[i][j]=-1;
    for(i=1;i<=n;++i)
        p[i][0]=a[i];
    for(j=1;j<=18;++j)
    for(i=0;i<=n;++i)
        if(p[i][j-1]!=-1)
            p[i][j]=p[p[i][j-1]][j-1];
    for(;m;--m)
    {
        scanf("%d %d\n",&x,&y);
        printf("%d\n",lca(n,p,a,l,x,y));
    }
    return 0;
}