Cod sursa(job #2324240)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 20 ianuarie 2019 14:25:59
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.88 kb
#include <bits/stdc++.h>
using namespace std ;
const int NMAX = 100001 ;
ifstream f ("lca.in") ;
ofstream g ("lca.out") ;

vector < int > v [ NMAX ] ;

int n , q , cnt , rmq_euler [ 20 ][ NMAX ] , firstap [ NMAX ] , euler [ 2 * NMAX ] , level [ NMAX ] , lg [ 2 * NMAX ] ;

void input()
{
    f >> n >> q ;
    for ( int i = 2 ; i <= n ; ++ i )
    {
        int father ;
        f >> father ;
        v [ father ].push_back( i ) ;
    }
}

void dfs ( int nod , int father )
{
    level [ nod ] = level [ father ] + 1 ;
    euler [ ++ cnt ] = nod ;
    firstap [ nod ] = cnt ;
    for ( size_t i = 0 ; i <  v[ nod ].size() ; ++ i )
    {
        dfs ( v [ nod ][ i ] , nod ) ;
        euler [ ++ cnt ] = nod ;
    }
}

void rmq ()
{
    int i , j ;
    for ( i = 2 ; i <= cnt ; ++ i )   lg [ i ] = lg [ i >> 1 ] + 1 ;

    for ( i = 1 ; i <= cnt ; ++ i )   rmq_euler [ 0 ][ i ] = euler [ i ] ;

    for( i = 1 ; ( 1 << i ) <= cnt ; ++ i )
    for( j = 1 ; j + ( 1 << i ) <= cnt + 1 ; ++ j )
    {
        rmq_euler [ i ][ j ] = rmq_euler [ i - 1 ][ j ] ;

        if ( level [ rmq_euler [ i ][ j ] ] > level [ rmq_euler [ i - 1 ][ j + 1 << ( i - 1 ) ] ] )
        rmq_euler [ i ][ j ] = rmq_euler [ i - 1 ][ j + ( 1 << ( i - 1 ) ) ] ;
    }
}

int query ( int x , int y )
{
    int st = firstap [ x ] ;
    int dr = firstap [ y ] ;

    if ( st > dr )  swap ( st , dr ) ;

    int i = lg [ dr - st + 1 ] ;

    if ( level [ rmq_euler [ i ][ st ] ] < level [ rmq_euler [ i ][ dr - ( 1 << i ) + 1 ] ] )
        return rmq_euler [ i ][ st ]  ;

        return rmq_euler [ i ][ dr - ( 1 << i ) + 1 ]  ;
}

void solve_query ()
{
    while ( q -- )
    {
        int x , y ;
        f >> x >> y ;
        g << query ( x , y ) << "\n" ;
    }
}


int main ()
{
    input() ;
    dfs ( 1 , 0 ) ;
    rmq() ;
    solve_query() ;
    return 0 ;
}