Cod sursa(job #1749866)

Utilizator catu_bogdan_99Catu Bogdan catu_bogdan_99 Data 28 august 2016 22:26:43
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.12 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

#define NMAX 100005
#define lgNNMAX 20

vector < int > v[ NMAX ];

int lg[ NMAX * 2 ];
int euler[ NMAX * 2 ];
int deep[ NMAX * 2 ];
int first[ NMAX * 2 ];
int rmq[ lgNNMAX ][ NMAX * 2 ];
int indi;

void computeLCA( int nod, int niv );
void computeRMQ();
int solveLCA( int x, int y );
int minim( int a, int b );

int main()
{

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

    int n, m, i, j, s, t, d, k, x, y;

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

    computeLCA( 1, 0 );
    //for( i = 1; i <= indi; ++i ) printf("%d ",deep[ i ]);

    computeRMQ( );

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

    return 0;

}

int minim( int a, int b ){
    if( a < b ) return a;
    return b;
}

int solveLCA( int x, int y ){

    x = first[ x ];
    y = first[ y ];

    if( x > y ) swap( x, y );

    int l = y - x + 1;
    int p = lg[ l ];

    //printf("-> %d %d\n",rmq[ p ][ x ], deep[ rmq[ p ][ x + ( 1 << p ) ] ] );
    int mina =  rmq[ p ][ y + 1 - ( 1 << p ) ] ;
    if(  deep[ rmq[p][x] ] < deep[ mina ] ) mina = rmq[p][x];

    return euler[ mina ];

}

void computeRMQ(){

    int i, j, rmq1;

    rmq[ 0 ][ 1 ] = 1;
    for( i = 2; i <= indi; ++i ){
        lg[ i ] = lg[ i / 2 ] + 1;
        rmq[ 0 ][ i ] = i;
    }

    for( i = 1; ( 1 << i ) < indi; ++i ){
        for( j = 1; j + ( 1 << i ) <= indi; ++j ){

            rmq[ i ][ j ] = rmq[ i - 1 ][ j ];
            int  p = 1 << ( i - 1 );
            rmq1 = rmq[ i - 1 ][ j + p ];
            if( deep[ rmq[ i ][ j ] ] > deep[ rmq1 ] ) rmq[ i ][ j ] = rmq1;
        }
    }

}

void computeLCA( int nod, int niv ){

    int i;

    euler[ ++indi ] = nod;
    deep[ indi ] = niv;
    first[ nod ] = indi;

    for( i = 0; i < v[ nod ].size(); ++i ){
        computeLCA( v[ nod ][ i ], niv + 1 );
        euler[ ++indi ] = nod;
        deep[ indi ] = niv;
    }

}