Cod sursa(job #2324323)

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

vector < int > v [ NMAX ] ;


    void dfs ( int nod , int father , int & cnt , int euler  [ 2 * NMAX ] , int level [ NMAX ] , int firstap [ NMAX ] )
    {
        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 , cnt , euler , level , firstap ) ;
            euler [ ++ cnt ] = nod ;
        }
    }

    void rmq ( int cnt , int rmq_euler [ LOGNMAX ][ 2 * NMAX ] , int level [ NMAX ] , int euler [ 2 * NMAX ] , int lg [ 2 * NMAX ] )
    {
        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 )
        {
            if ( level [ rmq_euler [ i - 1 ][ j ] ] > level [ rmq_euler [ i - 1 ][ j + ( 1 << ( i - 1 ) ) ] ] )
                        rmq_euler [ i ][ j ] = rmq_euler [ i - 1 ][ j + ( 1 << ( i - 1 ) ) ] ;
            else        rmq_euler [ i ][ j ] = rmq_euler [ i - 1 ][ j ] ;
        }
    }

    int query ( int x , int y , int firstap [ NMAX ] , int rmq_euler [ LOGNMAX ][ 2 * NMAX ] , int lg [ 2 * NMAX ] , int level [ NMAX ] )
    {
        int i , st , dr ;
        st = firstap [ x ] ;
        dr = firstap [ y ] ;
        if ( st > dr )  swap ( st , dr ) ;

        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 ]  ;
    }



int main ()
{
    int i ;

    int n , q , cnt = 0 , rmq_euler [ LOGNMAX ][ 2 * NMAX ] = {0} , firstap [ NMAX ] = {0} , euler [ 2 * NMAX ] = {0} , level [ NMAX ] = {0} , lg [ 2 * NMAX ] = {0};
   f >> n >> q ;
    for ( int i = 2 ; i <= n ; ++ i )
    {
        int father ;
        f >> father ;
        v [ father ].push_back( i ) ;
    }
    dfs ( 1 , 0 , cnt , euler , level , firstap ) ;
    rmq( cnt , rmq_euler , level , euler , lg ) ;
     while ( q -- )
    {
        int x , y ;
        f >> x >> y ;
        g << query ( x , y , firstap , rmq_euler , lg , level ) << "\n" ;
    }
    return 0 ;
}