Cod sursa(job #2220207)

Utilizator HumikoPostu Alexandru Humiko Data 10 iulie 2018 22:11:33
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.07 kb
#include <bits/stdc++.h>
#define nmax 100010

using namespace std;

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

int n, m, limit;
int first_Euler[4*nmax], logarithm[4*nmax], euler[4*nmax], level[4*nmax];
int dp[4*nmax][30];

vector <int> tree[nmax];

void eulerRepresentation(int node, int current_Level)
{
    euler[++limit] = node;
    level[limit] = current_Level;
    first_Euler[node] = limit;

    for ( auto x:tree[node] )
    {
        eulerRepresentation(x, current_Level+1);
        euler[++limit] = node;
        level[limit] = current_Level;
    }
}

void rangeMinimumQueryPrecalc()
{
    for ( int i = 2; i <= limit; ++i )
        logarithm[i] = logarithm[i/2]+1;
    for ( int i = 1; i <= limit; ++i )
        dp[i][0] = i;

    for ( int i = 1; i <= logarithm[limit]; ++i )
    {
        for ( int j = 1; j <= limit; ++j )
        {
            if ( j+(1<<i) > limit )
                break;

            if ( level[dp[j][i-1]] > level[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 answerQuery(int first_Value, int second_Value)
{
    int range = second_Value-first_Value+1;

    if ( level[dp[first_Value][logarithm[range]]] > level[dp[second_Value-(1<<logarithm[range])+1][logarithm[range]]] )
        return euler[dp[second_Value-(1<<logarithm[range])+1][logarithm[range]]];
    else
        return euler[dp[first_Value][logarithm[range]]];
}

int main()
{
    fin>>n>>m;
    for ( int i = 2; i <= n; ++i )
    {
        int father;
        fin>>father;
        tree[father].push_back(i);
    }

    eulerRepresentation(1, 0);
    rangeMinimumQueryPrecalc();

    for ( int i = 1; i <= m; ++i )
    {
        int a, b, first_Value, second_Value;
        fin>>a>>b;

        first_Value = first_Euler[a];
        second_Value = first_Euler[b];

        if ( first_Value > second_Value )
            swap(first_Value, second_Value);

        fout<<answerQuery(first_Value, second_Value)<<'\n';
    }
}