Cod sursa(job #2205535)

Utilizator HumikoPostu Alexandru Humiko Data 19 mai 2018 14:28:23
Problema Lowest Common Ancestor Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <bits/stdc++.h>
#define nmax 100010

using namespace std;

ifstream fin ("lca.in");
ofstream fout ("lca.out");

vector <int> v[2*nmax];
int n, m, k;
int logaritm[2*nmax], euler[2*nmax], nivel[2*nmax], prima[2*nmax];
int dp[4*nmax][20]; // dp[i][j], minimul dintre pozitia j si j+2^(i-1);

void dfs( int nod, int unde )
{
    euler[++k] = nod;
    nivel[k] = unde;
    prima[nod] = k;
    for ( auto x:v[nod] )
    {
        dfs(x, unde+1);
        euler[++k] = nod;
        nivel[k] = unde;
    }
}

void rmq()
{
    for ( int i = 2; i <= k; ++i )
        logaritm[i] = logaritm[i/2]+1;
    for ( int i = 1; i <= k; ++i )
        dp[i][0] = i;
    for ( int i = 1; i <= logaritm[k]; ++i )
    {
        for ( int j = 1; j <= k; ++j )
        {
            if ( j+(1<<(i-1)) > k )
                break;
            if ( nivel[dp[j][i-1]] > nivel[dp[j+(1<<(i-1))][i-1]] )
                dp[j][i] = dp[j+(1<<(i-1))][i-1];
            else
                dp[j][i] = dp[j][i-1];
        }
    }
}

int lca(int x, int y)
{
    if ( nivel[dp[x][logaritm[y-x]]] > nivel[dp[y-(1<<logaritm[y-x])][logaritm[y-x]]] )
        return euler[dp[y-(1<<logaritm[y-x])][logaritm[y-x]]];
    return euler[dp[x][logaritm[y-x]]];
}

int main()
{
    ios::sync_with_stdio(false);
    fin.tie(0); fout.tie(0);
    fin>>n>>m;
    for ( int i = 2; i <= n; ++i )
    {
        int tata;
        fin>>tata;
        v[tata].push_back(i);
    }
    dfs(1, 0);
    rmq();
    while ( m-- )
    {
        int x, y, a, b;
        fin>>a>>b;
        x = prima[a];
        y = prima[b];
        if ( x > y )
            swap (x, y);
        fout<<lca(x, y)<<'\n';
    }
}