Cod sursa(job #2310482)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 31 decembrie 2018 18:50:18
Problema Lowest Common Ancestor Scor 20
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.35 kb
#include <fstream>
#include <vector>
#include <algorithm>
#include <queue>
#define pb push_back
#define sz size()

using namespace std ;

ifstream f ( "lca.in" ) ;
ofstream g ( "lca.out" ) ;

const int NR = 1e5+5 ;
const int oo = (1 << 18 ) ;

vector < int > v [ NR ] ;
vector < bool > viz ( NR , false ) ;
vector < int > euler ( NR * 2 , 0 ) ;
vector < int > level ( NR , 0 ) ;
vector < int > primap ( NR , oo ) ;
int n , m , cnt ;
int a [ 2 * NR ][ 20 ] ;
int lg [ NR ] ;
void dfs ( int nod )
{
    viz [ nod ] = true ;

    for ( size_t i = 0 ; i < v [ nod ].sz ; ++ i )
        if( !viz [  v[  nod ][ i ] ] )
        {
            euler [ ++ cnt ] = nod ;
            primap [ nod ] = min ( cnt , primap [ nod ] ) ;
            level [ v [ nod ][ i ] ] = level [ nod ] + 1 ;
            dfs ( v [ nod ][ i ] ) ;

        }
    euler [ ++ cnt ] = nod ;
    primap [ nod ] = min ( cnt , primap [ nod ] ) ;
}

int main ()
{
    f >> n >> m ;
    int i , j ;
    for ( i = 2 ; i <= n ; ++ i )    { int a ; f >> a ; v [ a ].pb (i) ; v [ i ].pb (a) ;  }
    level [ 1 ] = 1 ;
    dfs (1) ;
    //for ( int i = 1 ; i <= cnt ; ++ i ) g << euler [ i ] << " " ;
    //g << "\n" ;
    //for ( int i = 1 ; i <= n ; ++ i ) g << level [ i ] << " " ;
    for ( i = 1 ; i <= cnt ; ++ i ) a [ i ][ 0 ] = i ;
    //g << "\n" ;
    //for ( i = 1 ;  i <= n ; ++ i )   g << primap [ i ] << ' ' ;
    //g <<"\n\n";
    for ( j = 1 ; ( 1 << j ) <= cnt ; ++ j )
    for ( i = 1 ; i + ( 1 << j ) <= cnt ; ++ i )

    if ( level [ euler [ a [ i ][ j - 1 ] ]  ] > level [ euler [ a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ] ] )
    a [ i ][ j ] = a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ;
    else
    a [ i ][ j ] = a [ i ][ j - 1 ] ;
    for ( i = 2 ; i <= n ; i <<= 1 ) lg [ i ] = 1 ;
    for ( i = 3 ; i <= n ; ++ i )   lg [ i ] += lg [ i - 1 ] ;
    while ( m -- )
    {
        int st , dr ; f >> st >> dr ;
        st = primap [ st ] ;
        dr = primap [ dr ] ;

        if ( dr < st )  swap ( st , dr ) ;
        //g << st << " " << dr << "\n" ;
        i = lg [ abs ( dr - st ) + 1 ] ;

        if ( level [ euler [ a [ st ][ i ] ] ] > level [ euler [ a [ dr - ( 1 << i ) + 1 ][ i ] ] ] )
            g << euler [ a [ dr - ( 1 << i ) + 1 ][ i ] ] << "\n" ;
        else
            g << euler [ a [ st ][ i ] ] << "\n" ;
    }
    return 0 ;
}