Cod sursa(job #557266)

Utilizator BitOneSAlexandru BitOne Data 16 martie 2011 15:41:07
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.58 kb
#include <vector>
#include <fstream>
#include <cstdlib>
#define N_MAX 100011
#define Log2N_MAX 20

using namespace std;
int Index;
int RMQ[Log2N_MAX][N_MAX];
int idx[N_MAX], level[N_MAX];
vector< int > G[N_MAX];
inline void GetEulerTur( int x, int lev )
{
    RMQ[0][++Index]=x;
    idx[x]=Index;
    level[x]=lev;
    if( G[x].empty() )
        return;
    vector< int >::const_iterator it=G[x].begin(), iend=G[x].end();
    for( ; it < iend; ++it )
        if( 0 == idx[*it] )
        {
            GetEulerTur( *it, lev+1 );
            RMQ[0][++Index]=x;
        }
}
inline int log2( int N )
{
    return ( 31-__builtin_clz(N) );
}
inline int LCA( int x, int y )
{
    if( idx[x] > idx[y] )
        swap( x, y );
    int idxX=idx[x], idxY=idx[y], l2;
    l2=log2( idxY-idxX+1 );
    if( level[RMQ[l2][idxX]] <= level[RMQ[l2][idxY-(1<<l2)+1]] )
        return RMQ[l2][idxX];
    return RMQ[l2][idxY-(1<<l2)+1];
}
int main( void )
{
    int N, M, x, y, i, till, log2Idx;
    ifstream in( "lca.in" );
    in>>N>>M;
    for( x=2; x <= N; ++x )
    {
        in>>y;
        G[y].push_back(x);
    }
    GetEulerTur( 1, 0 );
    log2Idx=log2( Index );
    for( x=y=1; x <= log2Idx; ++x, y*=2 )
    {
        till=Index-2*y+1;
        for( i=1; i <= till; ++i )
            if( level[RMQ[x-1][i]] <= level[RMQ[x-1][i+y]] )
                RMQ[x][i]=RMQ[x-1][i];
            else RMQ[x][i]=RMQ[x-1][i+y];
    }
    ofstream out( "lca.out" );
    for( ; M; --M )
    {
        in>>x>>y;
        out<<LCA( x, y )<<'\n';
    }
    return EXIT_SUCCESS;
}