Cod sursa(job #1687987)

Utilizator gabib97Gabriel Boroghina gabib97 Data 13 aprilie 2016 10:25:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.41 kb
#include <stdio.h>
#include <vector>
using namespace std;
int n,m,i,x,y,e[200001],nr,t[100001],r[200001][19],lg[200001],niv[100001],f[100001];
bool o[100001];
vector<int> G[100001];
void DFS(int s)
{
    int i,z=G[s].size();
    o[s]=1; e[++nr]=s;
    for (i=0;i<z;i++)
        if (!o[G[s][i]])
    {
        niv[G[s][i]]=niv[s]+1;
        DFS(G[s][i]);
        e[++nr]=s;
    }
}
void rmq()
{
    int i,l=1,p=2,j;
    for (i=1;i<=nr;i++) r[i][0]=e[i];
    for (j=1;p<=nr;j++)
    {
        for (i=1;i<=nr-p+1;i++)
            if (niv[r[i][j-1]]<niv[r[i+l][j-1]])
                r[i][j]=r[i][j-1];
            else
                r[i][j]=r[i+l][j-1];

        l=p;
        p<<=1;
    }
    l=0; p=2;
    for (i=1;i<=nr;i++)
    {
        if (i==p) {l++; p<<=1;}
        lg[i]=l;
    }
}
int lca(int x,int y)
{
    int l=lg[y-x+1];
    if (niv[r[x][l]]<niv[r[y-(1<<l)+1][l]])
        return r[x][l];
    else return r[y-(1<<l)+1][l];
}
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=nr;i>=1;i--) f[e[i]]=i;
    for (i=1;i<=m;i++)
    {
        scanf("%i%i",&x,&y);
        printf("%i\n",lca(min(f[x],f[y]),max(f[x],f[y])));
    }
    fclose(stdin);
    fclose(stdout);
    return 0;
}