Cod sursa(job #462150)

Utilizator BitOneSAlexandru BitOne Data 9 iunie 2010 20:48:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.69 kb
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iterator>
#define MAX_N 100011
#define MAX_2N 200023
#define MAX_LOGN 19

/*
 *
 */
using namespace std;
int indx;
int RMQ[MAX_2N][MAX_LOGN];
int idx[MAX_N], level[MAX_N];
vector< int > G[MAX_N];
inline void GetEulerTour( int x, int lev )
{
    level[x]=lev;
    RMQ[++indx][0]=x;
    idx[x]=( idx[x] <= indx ? idx[x] : indx );
    if( G[x].empty() )
        return;
    vector< int >::const_iterator it=G[x].begin(), iend=G[x].end();
    for( ; it < iend; ++it )
    {
        GetEulerTour( *it, lev+1 );
        RMQ[++indx][0]=x;
    }
}
inline int Log2( int N )
{
    int log2, p2;
    for( log2=0, p2=1; p2 <= N; ++log2, p2<<=1 );
    return log2-1;
}
inline int LCA( int x, int y )
{
    if( idx[x] > idx[y] )
        swap( x, y );
    int px=idx[x], py=idx[y], k=Log2( py-px+1 );
    if( level[RMQ[px][k]] <= level[RMQ[py-(1<<k)+1][k]] )
        return RMQ[px][k];
    else return RMQ[py-(1<<k)+1][k];
}
int main( void )
{
    int N, M, i, j, jdx, till, x, y, Log2N;
    ifstream in( "lca.in" );
    in>>N>>M;
    idx[1]=idx[0]=3*N;
    for( i=2; i <= N; ++i )
    {
        in>>x;
        idx[i]=3*N;
        G[x].push_back(i);
    }
    GetEulerTour(1,0);
    for( j=1, Log2N=Log2(indx); j <= Log2N; ++j )
    {
        jdx=1<<(j-1);
        till=indx-2*jdx+1;
        for( i=1; i <= till; ++i )
            if( level[RMQ[i][j-1]] <= level[RMQ[i+jdx][j-1]] )
                RMQ[i][j]=RMQ[i][j-1];
            else RMQ[i][j]=RMQ[i+jdx][j-1];
    }
    ofstream out("lca.out");
    for( ; M; --M )
    {
        in>>x>>y;
        out<<LCA( x, y )<<'\n';
    }
    return EXIT_SUCCESS;
}