Cod sursa(job #999866)

Utilizator thewildnathNathan Wildenberg thewildnath Data 21 septembrie 2013 16:25:03
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.39 kb
#include<stdio.h>
#include<vector>
using namespace std;
int h[300002],d[100002][20],l[300002],Log[20],e[300002];
vector <int> v[100002];

void rmq()
{
    int i,j;
    Log[1]=0;
    for(i=2;i<=e[0];++i)
        Log[i]=Log[i/2]+1;
    for(i=1;i<=e[0];++i)
        d[0][i]=i;
    for(i=1;(1<<i)<=e[0];++i)
        for(j=1;j<=e[0]-(1<<i)+1;++j)
            if(l[d[i-1][j]]<l[d[i-1][j+(1<<(i-1))]])
                d[i][j]=d[i-1][j];
            else
                d[i][j]=d[i-1][j+(1<<(i-1))];
}

void dfs(int x,int niv)
{
    e[++e[0]]=x;
    l[e[0]]=niv;
    h[x]=e[0];
    for(vector<int> ::iterator it=v[x].begin();it!=v[x].end();++it)
    {
        dfs(*it,niv+1);
        e[++e[0]]=x;
        l[e[0]]=niv;
    }
}

int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);
    int n,m,i,j,x,y,aux,nr;
    scanf("%d%d",&n,&m);
    for(i=2;i<=n;++i)
    {
        scanf("%d",&x);
        v[x].push_back(i);
    }
    dfs(1,0);
    rmq();
    for(i=1;i<=m;++i)
    {
        scanf("%d%d",&x,&y);
        if(h[x]>h[y])
        {
            aux=y;
            x=y;
            y=aux;
        }
        aux=Log[h[y]-h[x]+1];
        nr=h[y]-h[x]+1-(1<<aux);
        if(h[d[aux][h[x]]]<h[d[aux][h[x]+nr]])
            printf("%d\n",e[d[aux][h[x]]]);
        else
            printf("%d\n",e[d[aux][h[x]+nr]]);

    }
    return 0;
}