Cod sursa(job #1403296)

Utilizator BLz0rDospra Cristian BLz0r Data 27 martie 2015 10:41:10
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.61 kb
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

#define Nmax 100002
#define Lmax 20
#define pb push_back

FILE *f = fopen ( "lca.in", "r" );
FILE *g = fopen ( "lca.out", "w" );

vector < int > G[Nmax];
int rmq[Lmax][Nmax<<1], Eu[Nmax<<1], First[Nmax], Niv[Nmax<<1], lg[Nmax<<1], k, N, M;

void DFS ( int nod, int niv ){
    vector < int > :: iterator it;

    Eu[++k] = nod;
    Niv[k] = niv;
    First[nod] = k;

    for ( it = G[nod].begin(); it < G[nod].end(); ++it ){
        DFS ( *it, niv + 1 );
        Eu[++k] = nod;
        Niv[k] = niv;
    }

}

void RMQ (){

     for ( int i = 2; i <= k; ++i )
        lg[i] = lg[i>>1] + 1;

    for ( int i = 1; i <= k; ++i )
        rmq[0][i] = i;

    for ( int i = 1; ( 1 << i ) < k; ++i ){
        for ( int j = 1; j <= k - ( 1 << i ) ; ++j ){
            int t = ( 1 << ( i - 1 ) );
            rmq[i][j] = rmq[i-1][j];
            if ( Niv[rmq[i-1][j]] > Niv[rmq[i-1][j+t]] )
                rmq[i][j] = rmq[i-1][j+t];
        }
    }

}

int LCA ( int x, int y ){

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

    int dif = y - x + 1;
    int a = lg[dif];
    int t = dif - ( 1 << a );

    return Eu[ min ( rmq[a][x], rmq[a][x+t] ) ];
}

int main(){
    int x, y;

    fscanf ( f, "%d%d", &N, &M );

    for ( int i = 2; i <= N; ++i ){
        fscanf ( f, "%d", &x );
        G[x].pb ( i );
    }

    DFS ( 1, 0 );
    RMQ();

    for ( int i = 1; i <= M; ++i ){
        fscanf ( f, "%d%d", &x, &y );
        fprintf ( g, "%d\n", LCA ( First[x], First[y] ) );
    }

    return 0;
}