Cod sursa(job #1389573)

Utilizator iarbaCrestez Paul iarba Data 16 martie 2015 13:46:56
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.36 kb
#include <cstdio>
using namespace std;
int a[200001],m[200001][19],i,j,x,t,niv,nod[200001],la[100001];
int st[100001],sf[100001],next[100001],dest[100001];
int n,k,r,teste,rez;
int power2(int x){return 1<<x;}
int log2(int x)
{
    int y=0;
    while(x){y++;x/=2;}
    return y-1;
}
void add(int x, int y)
{
    t++;
    if(st[x]==0){st[x]=t;}
    else{next[sf[x]]=t;}
    sf[x]=t;
    next[t]=0;
    dest[t]=y;
}
void parc(int x)
{
    int j;
    a[++t]=niv;nod[t]=x;la[x]=t;m[t][0]=t;
    for(j=st[x];j;j=next[j])
    {
        niv++;
        parc(dest[j]);
        niv--;
        a[++t]=niv;nod[t]=x;la[x]=t;m[t][0]=t;
    }
}
int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&teste);
    t=0;
    for(i=2;i<=n;i++)
    {
        scanf("%d",&x);
        add(x,i);
    }
    niv=1;t=0;
    parc(1);
    k=log2(t);
    for(j=1;j<=k;j++)
    {
        r=power2(j);
        for(i=1;i<=n-r+1;i++)
        {
            if(a[m[i][j-1]]<a[m[i+r/2][j-1]]){m[i][j]=m[i][j-1];}
            else{m[i][j]=m[i+r/2][j-1];}
        }
    }
    while(teste--)
    {
        scanf("%d%d",&i,&j);
        i=la[i];j=la[j];
        k=log2(j-i+1);r=power2(k);
        if(a[m[i][j]]<a[m[j-r+1][k]]){rez=m[i][j];}
        else{rez=m[j-r+1][k];}
        printf("%d\n",nod[rez]);
    }
return 0;
}