Cod sursa(job #3163387)

Utilizator Mihai145Oprea Mihai Adrian Mihai145 Data 31 octombrie 2023 12:54:49
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.52 kb
//
// Created by mihai145 on 31.10.2023.
//

#include <fstream>
#include <vector>

using namespace std;

const int NMAX = 100000;
const int LOGMAX = 20;

int n, m;
vector<int> g[NMAX + 1];

int h[NMAX + 1], first[NMAX + 1];
vector<int> rmq[LOGMAX + 1];

void dfs(int node) {
    first[node] = (int) rmq[0].size();
    rmq[0].push_back(node);

    for (const auto &x: g[node]) {
        h[x] = h[node] + 1;
        dfs(x);
        rmq[0].push_back(node);
    }
}

void precompute() {
    int sz = (int) rmq[0].size();

    for (int i = 1; i <= LOGMAX; i++) {
        if ((1 << i) > sz) break;

        for (int j = 0; j < sz; j++) {
            if (j + (1 << i) > sz) break;

            if (h[rmq[i - 1][j]] <= h[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i].push_back(rmq[i - 1][j]);
            else
                rmq[i].push_back(rmq[i - 1][j + (1 << (i - 1))]);
        }
    }
}

inline int log2(int x) {
    int clz = __builtin_clz(x);
    return 31 - clz;
}

int query(int l, int r) {
    if (l > r) swap(l, r);

    int k = log2(r - l + 1);
    if (h[rmq[k][l]] <= h[rmq[k][r - (1 << k) + 1]]) return rmq[k][l];
    return rmq[k][r - (1 << k) + 1];
}

int main() {
    ifstream cin("lca.in");
    ofstream cout("lca.out");

    cin >> n >> m;
    for (int i = 2; i <= n; i++) {
        int p;
        cin >> p;
        g[p].push_back(i);
    }

    h[1] = 1;
    dfs(1);
    precompute();

    for (int i = 0; i < m; i++) {
        int u, v, k;
        cin >> u >> v;
        cout << query(first[u], first[v]) << '\n';
    }

    return 0;
}