Cod sursa(job #2172918)

Utilizator maria_sinteaMaria Sintea maria_sintea Data 15 martie 2018 19:02:04
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <iostream>
#include <cmath>
#include <vector>
#include <cstdio>
#define N 100005

using namespace std;

int n, mm, t, euler[N], niv[N], ap[N], nr, m[N][20];
vector <int> g[N];

void citire()
{
    scanf("%d %d\n", &n, &mm);
    for(int i=2;i<=n;i++)
    {
        scanf("%d ", &t);
        g[t].push_back(i);
    }
}

void dfs(int x, int ad)
{
    euler[++nr]=x;
    niv[nr]=ad;
    ap[x]=nr;
    for(int i=0;i<g[x].size();i++)
    {
        int nod=g[x][i];
        dfs(nod, ad+1);
        euler[++nr]=x;
        niv[nr]=ad;
    }
}

void matrice_rmq()
{
    for(int i=1;i<=nr;i++)
        m[i][0]=i;
    for(int j=1;(1<<j)<=nr;j++)
        for(int i=1;i<=nr-(1<<j)+1;i++)
            if(niv[m[i][j-1]]<niv[m[i+(1<<(j-1))][j-1]])
                m[i][j]=m[i][j-1];
            else
                m[i][j]=m[i+(1<<(j-1))][j-1];
}

int lca(int x, int y)
{
    int sol, a=ap[x], b=ap[y];
    if(a>b)
    {
        int aux=a;
        a=b;
        b=aux;
    }
    int k=log2(b-a+1);
    if(niv[m[a][k]]<=niv[m[b-(1<<k)+1][k]])
        sol=m[a][k];
    else
        sol=m[b-(1<<k)+1][k];
    return euler[sol];
}


int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    citire();
    dfs(1, 0);
    matrice_rmq();

    for(int i=1;i<=mm;i++)
    {
        int x, y;
        scanf("%d %d\n", &x, &y);
        printf("%d\n", lca(x, y));
    }
    return 0;
}