Cod sursa(job #3149418)

Utilizator PostoacaMateiMatei Postoaca PostoacaMatei Data 8 septembrie 2023 14:40:14
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

int n, q;
vector<int> gf[100001];
int tata[100001], niv[100001];
int p_curent, p_start[100001], p_end[100001];
int stramos[18][100001];

void dfs(int nod, int nvl = 1) {
    niv[nod] = nvl;
    p_start[nod] = ++p_curent;
    for (int fiu : gf[nod])
        dfs(fiu, nvl + 1);
    p_end[nod] = ++p_curent;
}

bool este_stramos(int x, int y) {
    // return true <=> x este stramos al lui y
    return p_start[x] <= p_start[y] && p_end[y] <= p_end[x];
}

void calculeaza_stramosi() {
    for (int nod = 1; nod <= n; ++nod)
        stramos[0][nod] = tata[nod];
    for (int p = 1; p < 18; ++p) // p < MAX_LOG
        for (int nod = 1; nod <= n; ++nod)
            stramos[p][nod] = stramos[p - 1][stramos[p - 1][nod]];
}

int lca(int x, int y) {
    if (este_stramos(x, y))
        return x;
    if (este_stramos(y, x))
        return y;
    for (int p = 17; p >= 0; p--) { // p = MAX_LOG - 1
        int z = stramos[p][x];
        if (z != 0 && !este_stramos(z, y))
            x = z;
    }
    return stramos[0][x];
}

int main() {
    fin >> n >> q;
    for (int i = 2; i <= n; i++) {
        fin >> tata[i];
        gf[tata[i]].push_back(i);
    }

    p_curent = 0;
    dfs(1);
    calculeaza_stramosi();

    for (int i = 1; i <= q; i++) {
        int x, y;
        fin >> x >> y;
        fout << lca(x, y) << "\n";
    }
    return 0;
}