Cod sursa(job #1749924)

Utilizator catu_bogdan_99Catu Bogdan catu_bogdan_99 Data 29 august 2016 11:16:13
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.79 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

#define NMAX 100005
#define maxLG 20

vector < int > v[ NMAX ];

/** Declarare LCA **/
int dim;
int N[ NMAX ], E[ NMAX * 2 ], F[ NMAX * 2 ];
/** Declarare RMQ **/
int lg[ NMAX * 2 ];
int rmq[ maxLG ][ NMAX * 2 ];

void computeRMQ( );
int LCA( int x, int y );
void computeLCA( int nod, int niv );


int main()
{
    freopen("lca.in","r",stdin);
    freopen("lca.out","w",stdout);

    int n, m, i, j, x, y;

    scanf("%d%d",&n,&m);
    for( i = 2; i <= n; ++i ){
        scanf("%d",&x);
        v[ x ].push_back( i );
    }

    computeLCA( 1, 0 ); ///calculeaza Euler si Adancimi
    computeRMQ( );///calculeaza RMQ

    while( m-- ){
        scanf("%d%d",&x,&y);
        printf("%d\n",LCA( x, y ));
    }

    return 0;
}

int LCA( int x, int y ){

    int a, b, dif;

    x = F[ x ]; y = F[ y ];
    if( x > y ) swap( x, y );

    dif = lg[ y - x + 1 ];
    a = rmq[ dif ][ x ];
    b = rmq[ dif ][ y + 1 - ( 1 << dif ) ];

    if( N[ a ] > N[ b ] ) a = b;
    return E[ a ];

}

void computeRMQ( ){

    int i, j, k, p, x, y;

    for( i = 1; i <= dim; ++i ) rmq[ 0 ][ i ] = i;
    for( i = 2; i <= dim; ++i ) lg[ i ] = lg[ i >> 1 ] + 1;

    for( i = 1; ( p = 1 << i ) < dim; ++i ){
        for( j = 1; j + p <= dim; ++j ){
            x = rmq[ i - 1][ j ];
            y = rmq[ i - 1 ][ j + p / 2 ];
            if( N[ x ] > N[ y ] ) x = y;
            rmq[ i ][ j ] = x;
        }
    }

}

void computeLCA( int nod, int niv ){

    dim++;
    E[ dim ] = nod; N[ dim ] = niv; F[ nod ] = dim;

    for( int i = 0; i < v[ nod ].size(); ++i ){
        computeLCA( v[ nod ][ i ], niv + 1 );
        dim++;
        E[ dim ] = nod; N[ dim ] = niv;
    }

}