Cod sursa(job #3338464)

Utilizator David_RadavoiRadavoi David Alexandru David_Radavoi Data 3 februarie 2026 15:46:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.6 kb
#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

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

#define NMAX 100000
#define LOG2 17

vector<int> arb[NMAX + 1];
vector<int> v;
int l[NMAX + 1];
int nivel[NMAX + 1];
int lg[2 * NMAX + 1];
int rmq[LOG2 + 1][2 * NMAX + 1];

void logar() {
    lg[1] = 0;
    for (int i = 2; i <= 2 * NMAX; i++)
        lg[i] = lg[i / 2] + 1;
}

void dfs(int node, int lvl) {
    nivel[node] = lvl;
    l[node] = v.size();
    v.push_back(node);
    for (int nxt : arb[node]) {
        dfs(nxt, lvl + 1);
        v.push_back(node);
    }
}

void build_rmq() {
    int N = v.size();
    for (int i = 0; i < N; i++)
        rmq[0][i] = v[i];
    for (int p = 1; (1 << p) <= N; p++) {
        for (int i = 0; i + (1 << p) <= N; i++) {
            int a = rmq[p - 1][i];
            int b = rmq[p - 1][i + (1 << (p - 1))];
            rmq[p][i] = (nivel[a] < nivel[b] ? a : b);
        }
    }
}

int lca(int a, int b) {
    int L = l[a];
    int R = l[b];
    if (L > R) swap(L, R);
    int p = lg[R - L + 1];
    int x = rmq[p][L];
    int y = rmq[p][R - (1 << p) + 1];
    return (nivel[x] < nivel[y] ? x : y);
}

int main() {
    ios::sync_with_stdio(false);
    fin.tie(nullptr);
    logar();
    int N, Q;
    fin >> N >> Q;
    for (int i = 1; i < N; i++) {
        int x;
        fin >> x;
        arb[x].push_back(i + 1);
    }
    dfs(1, 1);
    build_rmq();
    for (int i = 1; i <= Q; i++){
        int a, b;
        fin >> a >> b;
        fout << lca(a, b) << '\n';
    }
    return 0;
}