Cod sursa(job #2083190)

Utilizator AlexAxeToporan Victor AlexAxe Data 7 decembrie 2017 10:43:53
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.29 kb
#include <iostream>
#include <fstream>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");

const int NMax = 1e5 + 2;
int N, M;
int A[21][NMax], Log[NMax], Nivel[NMax];

void Read(){
    in >> N >> M;
    for (int i = 2; i <= N; ++i)
        in >> A[0][i];
}

void Lvl(int Nod){
    int Contor = 0, Aux = Nod;
    while (A[0][Nod]){
        Nod = A[0][Nod];
        Contor ++;
    }
    Nivel[Aux] = Contor;
}

void Precalculate(){
    for(int i = 1 ; 1<<i <= N ; ++i)
        for(int j = 1 ; j <= N ; ++j)
            A[i][j] = A[i-1][A[i-1][j]];
    for(int i = 2; i <= N ; ++i)
        Log[i] = Log[i/2] + 1;
    for(int i = 1; i <= N ; ++i)
        Lvl(i);
}

int LCA(int x, int y){
    if (Nivel[x] < Nivel[y]){
        swap(x, y);
    }
    while (Nivel[x] != Nivel[y]){
        int k = Log[Nivel[x] - Nivel[y]];
        x = A[k][x];
    }
    if (x == y)
        return x;
    for (int i = Nivel[x]; i >= 0; --i)
        if (A[i][x] != A[i][y]){
            x = A[i][x];
            y = A[i][y];
    }
    return A[0][x];
}

void SolveAndPrint(){
    Precalculate();
    while (M--){
        int Q, P;
        in >> Q >> P;
        out << LCA(Q, P) << '\n';
    }
}

int main()
{
    Read();
    SolveAndPrint();
    return 0;
}