Cod sursa(job #1383779)

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

using namespace std;

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

const int nmax = 100000;
const int nrmax = 2 * nmax;
const int inf = 1 << 30;
int sol, h[ nmax + 2 ], index[ nmax + 1 ];
int ai[ 4 * 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 update( int nod, int x, int y, int pos, int val ) {
    if ( x == y ) {
        ai[ nod ] = val;
        return ;
    }
    int mid = (x + y) / 2;
    if ( pos <= mid ) {
        update( (nod << 1) , x, mid, pos, val );
    } else {
        update( (nod << 1) + 1, mid + 1, y, pos, val );
    }

    if ( h[ ai[ nod << 1 ] ] < h[ ai[ (nod << 1) + 1 ] ] ) {
        ai[ nod ] = ai[ nod << 1 ];
    } else {
        ai[ nod ] = ai[ (nod << 1) + 1 ];
    }
}
void query( int nod, int x, int y, int st, int dr ) {
    if ( st <= x && y <= dr ) {
        if ( h[ sol ] > h[ ai[ nod ] ] ) {
            sol = ai[ nod ];
        }
        return ;
    }
    int mid = (x + y) / 2;
    if ( st <= mid ) {
        query( nod << 1, x, mid, st, dr );
    }
    if ( dr > mid ) {
        query( (nod << 1) + 1, mid + 1, y, st, dr );
    }
}
int main() {
    int n, m, t, nr;
    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 );

    nr = ( int )e.size() - 1;
    for( int i = 1; i <= nr; ++ i ) {
        update( 1, 1, nr, i, e[ i ] );
    }

    h[ nmax + 1 ] = inf;
    while ( m -- ) {
        int x, y;
        fin >> x >> y;
        if ( index[ x ] > index[ y ] ) {
            x ^= y ^= x ^= y;
        }
        sol = nmax + 1;
        query( 1, 1, nr, index[ x ], index[ y ] );
        fout << sol << "\n";
    }
    fin.close();
    fout.close();
    return 0;
}