Cod sursa(job #2310558)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 1 ianuarie 2019 14:57:24
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.32 kb
#include <iostream>
#include <fstream>
#include <cstring>
#include <vector>
#include <deque>
#include <queue>
#include <iomanip>
#include <algorithm>
#define pb push_back
#define sz size()

using namespace std ;

const int NR = 100001 ;
const int oo = 1 << 30 ;

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

vector < int > v [ NR ] ;
vector < bool > viz ( NR , false ) ;
vector < int > euler ( 2 * NR ) ;
vector < int > level ( NR , oo ) ;
vector < int > frst ( NR ) ;

int n , q , cnt ;

void input ()
{
    f >> n >> q ;
    for ( size_t i = 2 ; i <= n ; ++ i )
    {
        int x ; f >> x ; v [ i ].pb( x ) ; v [ x ].pb( i ) ;
    }
    level [ 1 ] = 0 ;
}

void dfs_euler ( int nod )
{
    viz [ nod ] = true ;
    frst [ nod ] = cnt + 1 ;
    for ( size_t i = 0 ; i < v [ nod ].sz ; ++ i )
    if ( !viz [ v [ nod ][ i ] ] )
    {
        euler [ ++ cnt ] = nod ;
        level [ v [ nod ][ i ] ] = min ( level [ nod ] + 1 , level [ v [ nod ][ i ] ] )  ;
        dfs_euler ( v [ nod ][ i ] ) ;
    }
    euler [ ++ cnt ] = nod ;
}

int a [ 2 * NR ][ 20 ] ;
int lg [ 2 * NR ] ;

void rmq ( )
{
    for ( size_t i = 1 ; i <= cnt ; ++ i )  a [ i ][ 0 ] = i ;

    for ( size_t j = 1 ; ( 1 << j ) <= cnt ; ++ j )
    for ( size_t 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 ][ j - 1 ] ;
    else
    a [ i ][ j ] = a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ;

    for ( size_t i = 2 ; i <= cnt ; i <<= 1 )   lg [ i ] = 1 ;
    for ( size_t i = 3 ; i <= cnt ; ++ i )      lg [ i ] += lg [ i - 1 ] ;
}

void task ( int x , int y )
{
    int st = frst [ x ] ;
    int dr = frst [ y ] ;
    if ( st > dr )    swap ( st , dr ) ;
    int i = dr - st + 1 ;
    if ( level [ euler [ a[ st ][ lg [ i ] ] ] ] > level [ euler [ a [ dr - ( 1 << ( lg [ i ] ) ) + 1 ][ lg [ i ] ] ] ] )
        g << euler [ a [ dr - ( 1 << ( lg [ i ] ) ) + 1 ][ lg [ i ] ] ] << "\n" ;
    else
        g << euler [ a[ st ][ lg [ i ] ] ] << "\n" ;
}

void solve_tasks ()
{
    int x, y ;
    for( size_t i = 0 ; i < q ; ++ i )
    {
    f >> x >> y ;
    task ( x , y ) ;
    }
}

int main ()
{
    input() ;
    dfs_euler ( 1 ) ;
    rmq() ;
    solve_tasks() ;
    return 0 ;
}