Cod sursa(job #461982)

Utilizator BitOneSAlexandru BitOne Data 9 iunie 2010 14:58:39
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.66 kb
#include <vector>
#include <cstdlib>
#include <fstream>
#include <iterator>
#define MAX_N 100011
#define MAX_2N 200023
#define MAX_LOG2N 18

/*
 *
 */
using namespace std;
int indx;
int RMQ[MAX_2N][MAX_LOG2N];
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 );
    vector< int >::const_iterator it=G[x].begin(), iend=G[x].end();
    for( it=G[x].begin(), iend=G[x].end(); it < iend; ++it )
    {

        GetEulerTour( *it, lev+1 );
        RMQ[++indx][0]=x;
    }
}
inline int Log2( int N )
{
    int r;
    for( r=0; (1<<r) <= N; ++r );
    return r-1;
}
inline int LCA( int x, int y )
{
    if( idx[x] > idx[y] )
        swap( x, y );
    int k=Log2( idx[y]-idx[x]+1);
    if( level[RMQ[idx[x]][k]] <= level[RMQ[idx[y]-(1<<k)+1][k]] )
        return RMQ[ idx[x] ][k];
    return RMQ[idx[y]-(1<<k)+1] [k];
}
int main( void )
{
    int N, M, i, j, jdx, till, x, y;
    ifstream in( "lca.in" );
    in>>N>>M;
    idx[1]=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; (1<<j) <= N; ++j )
    {
        jdx=1<<(j-1);
        till=2*N-2*jdx;
        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;
        x=LCA( x, y );
        out<<( x > 0 ? x : 1 )<<'\n';
    }
    return EXIT_SUCCESS;
}