Cod sursa(job #1671579)

Utilizator AlexVolatiluVoicu Alex AlexVolatilu Data 1 aprilie 2016 21:25:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <stdio.h>

using namespace std;

int ls[100005],urm[200010],vf[200010],vfls=1;
int nivel[100005];
int r[17][200015],log2[200015],primap[200015];

void add_ls(int x, int y)
{
    vf[vfls]=y;
    urm[vfls]=ls[x];
    ls[x]=vfls++;
}

void log2make(int n)
{
    int i;
    for(i=2;i<=n;i++)
        log2[i]=log2[i>>1]+1;
}

void parc_euler(int x)
{
    int p=ls[x],y;
    primap[x]=vfls;
    r[0][vfls++]=x;
    while(p!=0)
    {
        if(nivel[vf[p]]==0)
        {
            nivel[vf[p]]=nivel[x]+1;
            parc_euler(vf[p]);
            r[0][vfls++]=x;
        }
        p=urm[p];
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,i,j,k,np,a,b,l;
    scanf("%d%d",&n,&m);
    np=2*n-1;
    for(i=2;i<=n;i++)
    {
        scanf("%d",&j);
        add_ls(i,j);
        add_ls(j,i);
    }
    vfls=1;
    nivel[1]=1;
    parc_euler(1);
    log2make(np);

    for(i=1;i<=np;i++)
    {
        for(j=1;(1<<j)<=i;j++)
        {
            k=i-(1<<(j-1));
            r[j][i] = nivel[r[j-1][i]] <= nivel[r[j-1][k]] ? r[j-1][i] : r[j-1][k];
        }
    }

    for(i=0;i<m;i++)
    {
        scanf("%d%d",&a,&b);
        a=primap[a];
        b=primap[b];
        if(a>b) {l=a;a=b;b=l;}
        l=log2[b-a+1];
        k=nivel[r[l][b]] <= nivel[r[l][a+(1<<l)-1]] ? r[l][b] : r[l][a+(1<<l)-1];
        printf("%d\n",k);
    }

    return 0;
}