Cod sursa(job #2799333)

Utilizator Fantastic_Mantudor voicu Fantastic_Man Data 12 noiembrie 2021 21:51:38
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <fstream>
#include <vector>
using namespace std;
const int nmax = 2e5;
int v[nmax + 1];
vector < int > g[nmax + 1];
vector < int > euler;
vector < int > levels;
void dfs ( int nod, int level ) {
    euler.push_back ( nod );
    levels.push_back ( level );
    for ( auto x: g[nod] ) {
        dfs ( x, level + 1 );
        euler.push_back ( nod );
        levels.push_back ( level );
    }
}
int lg[2 * nmax + 1];
int first[nmax + 1];
int rmq[20][2 * nmax + 1];
void precalc_rmq ( int n ) {
    lg[1] = 0;
    for ( int i = 2; i <= n; i++ )
        lg[i] = lg[i / 2] + 1;
    for ( int i = 0; i < n; i++ )
        rmq[0][i] = i;
    for ( int i = 1; ( 1 << i ) <= n; i++ )
        for ( int j = 0; j < n - ( 1 << i ) + 1; j++ )
            rmq[i][j] = ( levels[rmq[i - 1][j]] < levels[rmq[i - 1][j + ( 1 << ( i - 1 ) )]] ? rmq[i - 1][j] : rmq[i - 1][j + ( 1 << ( i - 1 ) )] );
}
int query ( int a, int b ) {
    int x = first[a] - 1, y = first[b] - 1, l;
    if ( x > y )
        swap ( x, y );
    l = lg[y - x + 1];
    return ( levels[rmq[l][x]] < levels[rmq[l][y - ( 1 << l ) + 1]] ? euler[rmq[l][x]] : euler[rmq[l][y - ( 1 << l ) + 1]] );
}
ifstream fin ( "lca.in" );
ofstream fout ( "lca.out" );
int main () {
    int n, q, a, b;
    fin >> n >> q;
    for ( int i = 1; i < n; i++ ) {
        fin >> a;
        g[a].push_back ( i + 1 );
    }
    dfs ( 1, 1 );
    int i = 1;
    for ( auto x: euler ) {
        if ( first[x] == 0 )
            first[x] = i;
        i++;
    }
    precalc_rmq ( euler.size() );
    while ( q-- ) {
        fin >> a >> b;
        fout << query ( a, b ) << '\n';
    }
    
    return 0;
}