Cod sursa(job #2310721)

Utilizator Andrei-27Arhire Andrei Andrei-27 Data 1 ianuarie 2019 21:55:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <bits/stdc++.h>
#define pb push_back
#define sz size()
using namespace std ;
const int NR = 100001 ;
ifstream f ("lca.in") ;
ofstream g ("lca.out") ;
vector < int > v [ NR ] ;
int level [ NR ], firstap [ NR ] , euler [ 2 * NR ] , lg [ 2 * NR ] , a[ 2 * NR ][ 20 ] , n , q , cnt  ;
void input()
{
    f >> n >> q ;
    for ( int i = 2 ; i <= n ; ++ i )
        {
        int father ;    f >> father ;
        v [ father ].pb( i ) ;
        }
    level [ 0 ] = -1 ;
}
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 ].sz ; ++ i )
                            {   dfs ( v [ nod ][ i ] , nod ) ;
                            euler [ ++ cnt ] = nod ;    }
}
void rmq (){
    a [ 1 ][ 0 ] = euler [ 1 ] ;
    for ( int i = 2 ; i <= cnt ; ++ i )
    {
        lg [ i ] = lg [ i >> 1 ] + 1 ;
        a [ i ][ 0 ] = euler [ i ] ;
    }
    for( int j = 1 ; ( 1 << j ) <= cnt ; ++ j )
    for( int i = 1 ; i + ( 1 << j ) <= cnt + 1 ; ++ i )
    {
        a [ i ][ j ] = a [ i ][ j - 1 ] ;
        if ( level [ a [ i ][ j ] ] > level [ a [ i +  ( 1 << ( j - 1 ) )  ][ j - 1 ] ] )
        a[ i ][ j ] = a [ i + ( 1 << ( j - 1 ) ) ][ j - 1 ] ;
    }}
void task ( int x , int y )
{
     x = firstap [ x ] ;
     y = firstap [ y ] ;
    if ( x > y )  swap ( x , y ) ;
    int i = lg [ y - x + 1 ] ;
    if ( level [ a [ x ][ i ] ] < level [ a [ y - ( 1 << i ) + 1 ][ i ] ] )
        g << a [ x ][ i ] << "\n" ;
    else
        g << a [ y - ( 1 << i ) + 1 ][ i ] << "\n" ;}
void solve_tasks ()     {
    while ( q -- )
                        {int x , y ; f >> x >> y ;
                        task ( x , y ) ;}}
int main ()
{
    input() ;
    dfs ( 1 , 0 ) ;
    rmq() ;
    solve_tasks() ;
    return 0 ;}