Cod sursa(job #2083187)

Utilizator AlexAxeToporan Victor AlexAxe Data 7 decembrie 2017 10:33:17
Problema Lowest Common Ancestor Scor 40
Compilator cpp Status done
Runda Arhiva educationala Marime 1.23 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];

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

int Lvl(int Nod){
    int Contor = 0;
    while (A[0][Nod]){
        Nod = A[0][Nod];
        Contor ++;
    }
    return 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;
    }
}

int LCA(int x, int y){
    if (Lvl(x) < Lvl(y)){
        swap(x, y);
    }
    while (Lvl(x) != Lvl(y)){
        int k = Log[Lvl(x) - Lvl(y)];
        x = A[k][x];
    }
    if (x == y)
        return x;
    for (int i = Lvl(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;
}