Cod sursa(job #2083191)

Utilizator AlexAxeToporan Victor AlexAxe Data 7 decembrie 2017 10:49:13
Problema Lowest Common Ancestor Scor 90
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], Level[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 ++;
    }
    Level[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 (Level[x] < Level[y])
        swap(x, y);
    while (Level[x] != Level[y]){
        int k = Log[Level[x] - Level[y]];
        x = A[k][x];
    }
    if (x == y)
        return x;
    for (int i = Log[Level[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;
}