Cod sursa(job #582142)

Utilizator drywaterLazar Vlad drywater Data 14 aprilie 2011 22:30:53
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.53 kb
#include <stdio.h>
int n,m,i,rmq[20][100001],h[200001],l[200001],first[100001],x;
struct nod{int y; nod *next;};
int lg[100002];
nod *G[100001];
int add(int a,int b)
{
    nod *nou=new nod;
    nou->y=b;
    nou->next=G[a];
    G[a]=nou;
    return 0;
}
int dfs(int n,int lev)
{
    h[++h[0]]=n;
    l[h[0]]=lev;
    first[n]=h[0];
    nod *it=new nod;
    it=G[n];
    while (it)
    {
        dfs(it->y,lev+1);
        h[++h[0]]=n;
        l[h[0]]=lev;
        it=it->next;
    }
}
int Rmq()
{
    for (i=2;i<=h[0];i++)
        lg[i]=lg[i/2]+1;
    for (i=1;i<=h[0];i++)
        rmq[0][i]=i;
    int j,lo;
    for (i=1;(1<<i)<h[0];i++)
    {
        lo=(1<<(i-1));
        for (j=1;j+2*lo<=h[0];j++)
        {
            rmq[i][j]=rmq[i-1][j];
            if (l[rmq[i][j]]>l[rmq[i-1][j+lo]])
                rmq[i][j]=rmq[i-1][j+lo];
        }
    }
    return 0;
}
int LCA(int x,int y)
{
    int a,b,aux,lo,diff;
    a=first[x];
    b=first[y];
    if (a>b) {aux=a; a=b; b=aux;}
    diff=b-a+1;
    lo=lg[diff];
    int sh=diff-(1<<lo);
    int sol=rmq[lo][a];
    if (l[sol]>l[rmq[lo][a+sh]])
        sol=rmq[lo][a+sh];
    return h[sol];
}
int main(void)
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    scanf("%d%d",&n,&m);
    for (i=2;i<=n;i++)
    {
        scanf("%d",&x);
        add(x,i);
    }
    dfs(1,0);
    Rmq();
    int a,b;
    for (i=1;i<=m;i++)
    {
        scanf("%d%d",&a,&b);
        printf("%d\n",LCA(a,b));
    }
    return 0;
}