Cod sursa(job #1464186)

Utilizator petru.cehanCehan Petru petru.cehan Data 22 iulie 2015 15:15:17
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.02 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;
}