Cod sursa(job #1216820)

Utilizator xtreme77Patrick Sava xtreme77 Data 5 august 2014 20:58:23
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.97 kb
#include <fstream>
#include <vector>

#define rint register int
#define pb push_back

const char IN [ ] = "lca.in" ;
const char OUT [ ] = "lca.out" ;
const int MAX = 100014;
const int LOGMAX = 22;

using namespace std;

ifstream fin ( IN ) ;
ofstream fout ( OUT ) ;

struct euler {
    int nivel , nod ;
};

euler q [ MAX << 1 ] ;

vector < int > gr [ MAX ] ;
int now , first [ MAX ] , R [ LOGMAX ] [ MAX ] , log [ MAX ] ;
void dfs ( int nod , int lvl )
{
    ++ now ;
    q [ now ].nivel = lvl ;
    q [ now ].nod = nod ;
    first [ nod ] = now ;
    for ( auto x : gr [ nod ] )
    {
        dfs ( x , lvl + 1 ) ;
        ++ now ;
        q [ now ].nivel = lvl ;
        q [ now ].nod = nod ;
    }
}
void RMQ ( int n )
{
    log [ 1 ] = 0 ;
    for ( rint i = 2 ; i <= n ; ++ i )
        log [ i ] = log [ i >> 1 ] + 1 ;
    for ( rint i = 1 ; i <= n ; ++ i )
        R [ 0 ] [ i ] = i ;
    for ( rint i = 1 ; (1 << i) <= n ; ++ i )
        for ( rint j = 1 ; j <= n - (1<<i) + 1 ; ++ j )
        {
            int l = 1 << ( i - 1 ) ;
            R [ i ] [ j ] = R [ i - 1 ] [ j ] ;
            if ( q [ R [ i ] [ j ] ].nivel > q [ R [ i - 1 ][ j + l ] ].nivel )
                R [ i ] [ j ] = R [ i - 1 ][ j + l ] ;
        }
}
int lca ( int x , int y )
{
    int a = first [ x ] ;
    int b = first [ y ] ;
    if ( a > b )
        swap ( a , b ) ;
    int diff = b - a + 1 ;
    int lg = log [ diff ] ;
    int sol = R [ lg ] [ a ] ;
    int sh = diff - (1 << lg) ;
    if ( q [ sol ].nivel > q[ R [ lg ] [ a + sh ] ].nivel )
        sol = R [ lg ] [ a + sh ];
    return q [ sol ].nod ;
}
int main( )
{
    int n , m ;
    fin >> n >> m ;
    for ( rint i = 2 ; i <= n ; ++ i )
    {
        int x ;
        fin >> x;
        gr [ x ] . pb( i ) ;
    }
    dfs ( 1 , 0 ) ;
    RMQ ( now ) ;
    while ( m -- )
    {
        int x, y ;
        fin >> x >> y ;
        fout << lca ( x , y ) << '\n' ;
    }
    return 0;
}