Cod sursa(job #1363776)

Utilizator felixiPuscasu Felix felixi Data 27 februarie 2015 11:10:16
Problema Lowest Common Ancestor Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.73 kb
#include <fstream>
#include <algorithm>
#include <vector>
#include <cmath>

using namespace std;

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

const int NMAX = 100000;
const int JMAX = 18;

vector <int> G[NMAX+1];
int N,M, E[2*NMAX+1], E_ind = 0, L[2*NMAX+1], Ind[2*NMAX+1];
int rmq[JMAX+1][2*NMAX+2];
bool viz[NMAX+2];

void DFS( int nod, int layer ) {
    viz[nod] = 1;

    E[ ++E_ind ] = nod;
    L[ E_ind ] = layer;
    Ind[nod] = E_ind;

    for( int i = 0;  i < (int)G[nod].size();  ++i ) {
        int x = G[nod][i];
        if( !viz[x] ) {
            DFS(x, layer+1);
            E[ ++E_ind ] = nod;
            L[ E_ind ] = layer;
        }
    }
}

void RMQ() {
    for( int i = 1;  i <= E_ind;  ++i )  rmq[0][i] = i;
    for( int j = 1;  j <= JMAX;  ++j ) {
        for( int i = 1;  i <= E_ind-(1<<j)+1;  ++i ) {
            if( L[ rmq[j-1][ i ] ] < L[ rmq[j-1][ i+( 1<<(j-1) ) ] ] ) {
                rmq[j][i] = rmq[j-1][ i ];
            }
            else {
                rmq[j][i] = rmq[j-1][ i+( 1<<(j-1) ) ];
            }
        }
    }
}

int main() {
    in >> N >> M;
    for( int i = 2;  i <= N;  ++i ) {
        int nr;  in >> nr;
        G[i].push_back(nr);
        G[nr].push_back(i);
    }
    DFS(1,0);
    RMQ();
    E[0] = 1;
    for( int i = 1;  i <= M;  ++i ) {
        int x,y;
        in >> x >> y;
        int sol, st = min( Ind[x], Ind[y] ), dr = max( Ind[x], Ind[y] );
        int lg = (int)log2( (dr-st+1)*1.0 );
        if( L[ rmq[lg][st] ] < L[ rmq[lg][dr - (1<<(lg-1)) + 1] ] ) {
            sol = rmq[lg][st];
        }
        else {
            sol = rmq[lg][dr - (1<<(lg-1)) + 1];
        }

        out << E[sol] << '\n';
    }
    return 0;
}