Cod sursa(job #3368717)

Utilizator G_b_yZamfirache Gabriel G_b_y Data 15 octombrie 2026 13:34:05
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.81 kb
#include <bits/stdc++.h>

using namespace std;

const int NMAX = 100005;
int N, M;
vector<int> vec[NMAX];
//  first - vertex, second - level
pair<int, int> euler[NMAX * 2 + 1];
int rmq[(int)log2(NMAX * 2) + 1][NMAX * 2 + 1];
int H[NMAX], lg2[NMAX * 2 + 2];

int& get_size() {
    return euler[0].first;
}

void push (int vertex, int level) {
    euler[++get_size()] = {vertex, level};
}

void tour (int x, int level = 1) {
    push(x, level);
    if (H[x] == 0) {
        H[x] = get_size();
    }
    for (auto y : vec[x]) {
        tour(y, level + 1);
        push(x, level);
    }
}

void init () {
    tour(1);
    long long p = 1;
    lg2[0] = -1;
    for (int i = 1; i <= N * 2; ++i) {
        rmq[0][i] = i;
        lg2[i] = lg2[i / 2] + 1;
    }
    for (int i = 1; i <= lg2[N * 2]; ++i) {
        for (int j = 1; j <= get_size() - p; ++j) {
            int v1 = rmq[i - 1][j], v2 = rmq[i - 1][j + p];
            if (euler[v1].second < euler[v2].second) {
                rmq[i][j] = v1;
            } else {
                rmq[i][j] = v2;
            }
        }
        p *= 2;
    }
}

int query (int a, int b) {
    int l = min(H[a], H[b]), r = max(H[a], H[b]);
    int i = lg2[r - l + 1];
    int offset = r - l + 1 - (1 << i);
    int ans;
    if (euler[rmq[i][l]].second < euler[rmq[i][l + offset]].second) {
        ans = rmq[i][l];
    } else {
        ans = rmq[i][l + offset];
    }
    return euler[ans].first;
}

int main () {
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    cin >> N >> M;
    for (int i = 2; i <= N; ++i) {
        int p;
        cin >> p;
        vec[p].push_back(i);
    }
    init();
    while (M--) {
        int a, b;
        cin >> a >> b;
        cout << query(a, b) << '\n';
    }
    return 0;
}