Cod sursa(job #3368713)

Utilizator G_b_yZamfirache Gabriel G_b_y Data 15 octombrie 2026 13:07:51
Problema Lowest Common Ancestor Scor 70
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.71 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> rmq[(int)log2(NMAX * 2) + 1][NMAX * 2];
int H[NMAX];
long long p2[(int)log2(NMAX * 2) + 1];

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

void push (int vertex, int level) {
    rmq[0][++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;
    p2[0] = 1;
    for (int i = 1; i <= (int)log2(N * 2); ++i) {
        p2[i] = p * 2;
        for (int j = 1; j <= get_size() - p; ++j) {
            pair<int, int> v1 = rmq[i - 1][j], v2 = rmq[i - 1][j + p];
            if (v1.second < 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 = log2(r - l + 1);
    int offset = r - l + 1 - p2[i];
    pair<int, int> ans;
    if (rmq[i][l].second < rmq[i][l + offset].second) {
        ans = rmq[i][l];
    } else {
        ans = rmq[i][l + offset];
    }
    return 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;
}