Cod sursa(job #3306306)

Utilizator razviii237Uzum Razvan razviii237 Data 9 august 2025 14:48:57
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.61 kb
// 1 2 4 7 4 8 4 2 5 2 6 9 6 2 1 3 10 3 11 3 1
//     |                 |
// 0 1 2 3 2 3 2 1 2 1 2 3 ...
//#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, m, x, y;
vector<int> v[100005];
vector<pair<int, int>> euler; // indexat de la 0
pair<int, int> rmq[400005][20]; // {nivel, nodul}
int ap[100005], first[100005];
void dfs(int nod, int nivel) {
    euler.push_back({nod, nivel});
    if(ap[nod] == 0) {
        ap[nod] = 1;
        first[nod] = euler.size() - 1;
    }
    for(auto u : v[nod]) {
        dfs(u, nivel + 1);
        euler.push_back({nod, nivel});
    }
}
int nrmq;
int lg[400001];
void precalculareRmq() {
    nrmq = euler.size();
    for(int i = 2; i <= nrmq; i ++) {
        lg[i] = lg[i/2] + 1;
    }
    for(int i = 0; i < nrmq; i ++)
        rmq[i][0] = {euler[i].second, euler[i].first};
    for(int i = 1; (1 << i) < nrmq; i ++) {
        for(int j = 0; j + (1 << i) - 1 < nrmq; j ++) {
            rmq[j][i] = min(rmq[j][i-1], rmq[j + (1 << (i-1))][i-1]);
        }
    }
}
int queryRmq(int st, int dr) {
    int lungime = dr - st + 1;
    int loga = lg[lungime];
    return min(rmq[st][loga], rmq[dr - (1 << loga) + 1][loga]).second;
}
int main() {
    cin >> n >> m;
    for(int i = 1; i <= n-1; i ++) {
        cin >> x;
        // x este tatal lui i+1
        v[x].push_back(i+1);
    }
    dfs(1, 0);
    precalculareRmq();
    for(int i = 1; i <= m; i ++) {
        cin >> x >> y;
        x = first[x];
        y = first[y];
        if(y < x)
            swap(x, y);
        cout << queryRmq(x, y) << '\n';
    }
    return 0;
}