Cod sursa(job #1365197)

Utilizator gabib97Gabriel Boroghina gabib97 Data 28 februarie 2015 10:21:56
Problema Lowest Common Ancestor Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 1.31 kb
#include <stdio.h>
#include <vector>
using namespace std;
int n,m,i,t[100001],r[100001][30],e[200001],log[200001],nr,w[30],v[100001],x,y,f[100001];
vector<int> G[100001];
void DFS(int s)
{
    int i,z=G[s].size();
    e[++nr]=s;
    for (i=0;i<z;i++)
    {
        v[G[s][i]]=v[s]+1;
        DFS(G[s][i]);
        e[++nr]=s;
    }
}
void rmq()
{
    int i,j,l,k;
    w[1]=2; w[0]=1; l=2*n-1;
    for (i=1;i<=l;i++) r[i][0]=e[i];
    for (j=1;w[j]<=l;j++)
    {
        w[j+1]=w[j]*2;
        for (i=1;i<=l-w[j]+1;i++)
            if (v[r[i][j-1]]<v[r[i+w[j-1]][j-1]])
                r[i][j]=r[i][j-1];
            else r[i][j]=r[i+w[j-1]][j-1];
    }
    for (i=l;i>=1;i--) f[e[i]]=i;
    k=2;
    for (i=1;i<=j;i++)
        for (l=1;l<=w[i];l++) log[k++]=i;
}
int lca(int i,int j)
{
    int k=log[j-i+1];
    if (v[r[i][k]]<v[r[j-w[k]+1][k]])
        return r[i][k];
    return r[j-w[k]+1][k];
}
int main()
{
    freopen ("lca.in","r",stdin);
    freopen ("lca.out","w",stdout);
    scanf("%i%i",&n,&m);
    for (i=2;i<=n;i++)
    {
        scanf("%i",&t[i]);
        G[t[i]].push_back(i);
    }
    DFS(1);
    rmq();
    for (i=1;i<=m;i++)
    {
        scanf("%i%i",&x,&y);
        printf("%i\n",lca(f[x],f[y]));
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}