Cod sursa(job #461854)

Utilizator BitOneSAlexandru BitOne Data 8 iunie 2010 20:09:01
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.93 kb
#include <vector>
#include <cstdlib>
#include <fstream>
#define Nmax 100011
#define LogNmax 17
#define SIZE 200003

/*
 *
 */
using namespace std;
ifstream in;
int idx;
char file[SIZE];
int t[Nmax], lev[Nmax];
int f[Nmax][LogNmax];
vector< int > G[Nmax];
inline void read( int& x )
{
    while( file[idx] < '0' || file[idx] > '9' )
        if( ++idx == SIZE )
        {
            idx=0;
            in.read( file, SIZE );
        }
    for( x=0; file[idx] >= '0' && file[idx] <= '9'; )
    {
        x=x*10+file[idx]-'0';
        if( ++idx == SIZE )
        {
            idx=0;
            in.read( file, SIZE );
        }
    }
}
inline void GetLevel( int x, int level )
{
    lev[x]=level;
    if( G[x].empty() )
        return;
    vector< int >::const_iterator it=G[x].begin(), iend=G[x].end();
    for( ; it < iend; ++it )
        GetLevel( *it, level+1 );
}
inline int LCA( int x, int y )
{
    int log2, j;
    if( lev[x] > lev[y] )
        swap( x, y );
    for( log2=0; (1<<log2) <= lev[y]; ++log2 );
    --log2;
    for( j=log2; j >= 0; --j )
        if( lev[y] - (1<<j) >= lev[x] )
            y=f[y][j];
    if( x == y )
        return x;
    for( j=log2; j >= 0; --j )
        if( -1 != f[x][j] && f[x][j] != f[y][j] )
            x=f[x][j], y=f[y][j];

    return t[x];
}
int main( void )
{
    int N, M, i, j;
    in.open( "lca.in" );
    read(N); read(M);
    for( i=0; i <= N; ++i )
        for( j=0; (1<<j) <= N; ++j )
            f[i][j]=-1;
    f[1][0]=1;
    t[1]=1;
    for( i=2; i <= N; ++i )
        read(t[i]), f[i][0]=t[i], G[t[i]].push_back(i);
    GetLevel( 1, 0 );
    for( j=1; (1<<j) < N; ++j )
        for( i=1; i <= N; ++i )
            if( -1 != f[i][j-1] )
                f[i][j]=f[f[i][j-1]][j-1];
    ofstream out( "lca.out" );
    for( ; M; --M )
    {
        read(i); read(j);
        out<<LCA( i, j )<<'\n';
    }
    return EXIT_SUCCESS;
}