Cod sursa(job #1464872)

Utilizator TeodorescuStefanEduardTeodorescu Stefan Eduard TeodorescuStefanEduard Data 25 iulie 2015 22:01:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.04 kb
#include <algorithm>
#include <vector>
#include <cstdio>
 
using namespace std ;
 
#define pb push_back
#define DIM 100005
#define LOG 20
 
int euler [ DIM << 1 ] ,l [ DIM << 1 ] , lg [ DIM << 1 ] , first_poz [ DIM ] ;
vector <int> Graph [DIM] ;
int rmq [ LOG ] [ DIM << 1 ] ;
int n , m , lg_euler ;
 
void read ()
{
    int i , x ;
 
    scanf ( "%d%d" , &n , &m ) ;
    for ( i = 2 ; i <= n ; ++ i )
    {
        scanf ("%d",&x) ;
        Graph [x].pb (i) ;
    }
}
 
void df ( int nod , int lev )  // Parcurgere Euler
{
    euler [ ++ lg_euler ] = nod ;
    l [ lg_euler ] = lev ;
    first_poz [nod] = lg_euler ;
 
    for ( unsigned int i = 0 ; i < Graph [nod].size () ; ++ i )
    {
        df ( Graph [nod][i] , lev + 1 ) ;
        euler [ ++ lg_euler ] = nod ;
        l [ lg_euler ] = lev ;
    }
}
 
void build_rmq ()
{
    int i , j ;
 
    for ( i = 2 ; i <= lg_euler ; ++ i ) // precalculez logaritmii..ca dupa sa fac in O (1)
        lg[i] = lg[ i>>1 ] + 1 ;
 
    for ( i = 1 ; i <= lg_euler ; ++ i )
        rmq[0][i] = i ;
 
    for ( i = 1 ; ( 1 << i ) < lg_euler ; ++ i )
        for (j = 1 ; j <= lg_euler - ( 1 << i ) ; ++ j )
 
            if ( l [rmq[i-1][j]] < l[rmq[i-1][ j + ( 1 << (i-1) ) ]] )
                rmq[i][j] = rmq[i-1][j] ;
            else
                rmq[i][j] = rmq[i-1][ j + ( 1 << (i-1) ) ] ;
}
 
void solve ()
{
    int i , x , y , lung ;
 
    for (i = 1 ; i <= m ; ++ i )
    {
        scanf ( "%d%d" , &x , &y ) ;
 
        x = first_poz [x] ;
        y = first_poz [y] ;
 
        if ( x > y )
            swap ( x , y ) ;
 
        lung = lg[ y - x + 1 ] ;
 
        if ( l [rmq[lung][x]] < l[rmq[lung][y - ( 1 << lung ) + 1]] )
            printf ( "%d\n" , euler [rmq[lung][x]] ) ;
 
        else
            printf ( "%d\n" , euler [rmq[lung][y-( 1 << lung ) + 1]] );
    }
}
 
int main ()
{
    freopen ("lca.in","r",stdin);
    freopen ("lca.out","w",stdout);
 
    read ();
    df (1,0);
    build_rmq ();
    solve ();
 
    return 0;
}