Cod sursa(job #1383790)

Utilizator laurageorgescuLaura Georgescu laurageorgescu Data 10 martie 2015 17:29:54
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.85 kb
#include<fstream>
#include<vector>

using namespace std;

ifstream fin( "lca.in" );
ofstream fout( "lca.out" );

const int nmax = 100000;
const int logmax = 17;
const int nrmax = 2 * nmax;
const int inf = 1 << 30;
int h[ nmax + 2 ], index[ nmax + 1 ];
int p2[ nrmax + 1 ], d[ logmax + 1 ][ nrmax + 1 ];
vector< int > g[ nmax ], e;

inline int min2( int a, int b ) {
    return ( a < b ? a : b );
}
void euler( int nod ) {
    index[ nod ] = min2( index[ nod ], ( int )e.size() );
    e.push_back( nod );
    for( vector< int >::iterator it = g[ nod ].begin(); it != g[ nod ].end(); ++ it ) {
        h[ *it ] = h[ nod ] + 1;
        euler( *it );
        e.push_back( nod );
    }
}
void rmq() {
    int nr = ( int )e.size() - 1;
    for( int i = 2; i <= nr; ++ i ) {
        p2[ i ] = p2[ i >> 1 ] + 1;
    }

    for( int i = 1; i <= nr; ++ i ) {
        d[ 0 ][ i ] = e[ i ];
    }

    for( int i = 1; (i << 1) <= nr; ++ i ) {
        for( int j = 1; j <= nr - (i << 1) + 1; ++ j ) {
            int a, b;
            a = d[ i - 1 ][ j ]; b = d[ i - 1 ][ j + (1 << (i - 1)) ];
            if ( h[ a ] < h[ b ] ) {
                d[ i ][ j ] = a;
            } else {
                d[ i ][ j ] = b;
            }
        }
    }
}
int query( int x, int y ) {
    if ( x > y ) {
        x ^= y ^= x ^= y;
    }
    int a, b, k = p2[ y - x + 1 ];
    a = d[ k ][ x ];
    b = d[ k ][ y - (1 << k) + 1 ];
    if ( h[ a ] < h[ b ] ) {
        return a;
    }
    return b;
}
int main() {
    int n, m, t;
    fin >> n >> m;
    for( int i = 2; i <= n; ++ i ) {
        fin >> t;
        g[ t ].push_back( i );
        index[ i ] = inf;
    }
    index[ 1 ] = inf;
    e.push_back( -inf );
    euler( 1 );

    rmq();

    while ( m -- ) {
        int x, y;
        fin >> x >> y;
        fout << query( index[ x ], index[ y ] ) << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}