Cod sursa(job #1768340)

Utilizator NicusorTelescu Nicolae Nicusor Data 30 septembrie 2016 19:06:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
#include <cstdio>

using namespace std;

int arbore[100001][19];

int inaltime(int i,int j)
{
    if (j==1)
    {
        arbore[j][0]=1;
        return 1;
    }

    if (arbore[j][0]!=0)
        return arbore[j][0];
    else
    {
        arbore[j][0]=inaltime(i,arbore[j][1])+1;
        return arbore[j][0];
    }
}

int nivel(int nod,int ajung)
{
    int i=1;
    if (arbore[ajung][0] - arbore[arbore[nod][1]][0] == 0)
        return arbore[nod][1];
    else
    {
        for (;arbore[arbore[nod][i]][0]>arbore[ajung][0];i++);
        return nivel(arbore[nod][i-1],ajung);
    }

}

int niveluri(int x,int y)
{
    int i=1;
    if (x!=y && arbore[x][1] == arbore[y][1])
        return arbore[x][1];
    else
    {
        for (;arbore[x][i]!=arbore[y][i] && arbore[x][i]!=0 ;i++);
        return niveluri(arbore[x][i-1],arbore[y][i-1]);
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m;
    scanf("%d %d\n",&n,&m);
    for (int i=2;i<=n;i++)
        scanf("%d ",&arbore[i][1]);
    for (int i=1;i<=n;i++)
        inaltime(i,i);
    for (int i=2;i<=17;i++)
        for (int j=1;j<=n;j++)
            arbore[j][i]=arbore[arbore[j][i-1]][i-1];

    for (int i=1;i<=m;i++)
    {
        int x,y,aux;
        scanf("%d %d",&x,&y);
        if (arbore[y][0]>arbore[x][0])
            y=nivel(y,x);
        else
            if (arbore[y][0]<arbore[x][0])
            x=nivel(x,y);
        if (x==y) printf("%d\n",x);
        else
            printf("%d\n",niveluri(x,y));
    }
}