Cod sursa(job #3333281)

Utilizator coco11coraline kalbfleisch coco11 Data 12 ianuarie 2026 17:57:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.05 kb
#include <bits/stdc++.h>
using namespace std;

int main() {
    fstream fin("lca.in", ios::in);
    fstream fout("lca.out", ios::out);
    ios::sync_with_stdio(false);
    cin.tie(nullptr);

    int n, m;
    fin >> n >> m;

    vector<vector<int>> adj(n + 1);
    vector<int> par(n + 1, 0);
    for (int i = 2; i <= n; ++i) {
        int p;
        fin >> p;
        par[i] = p;
        adj[p].push_back(i);
        adj[i].push_back(p);
    }

    int LOG = 1;
    while ((1 << LOG) <= n) ++LOG;

    vector<vector<int>> up(LOG, vector<int>(n + 1, 0));
    vector<int> depth(n + 1, 0);

    {
        vector<int> st;
        st.push_back(1);
        up[0][1] = 0;
        depth[1] = 0;
        vector<int> parent(n + 1, 0);
        parent[1] = 0;

        while (!st.empty()) {
            int u = st.back();
            st.pop_back();
            for (int v : adj[u]) {
                if (v == parent[u]) continue;
                parent[v] = u;
                up[0][v] = u;
                depth[v] = depth[u] + 1;
                st.push_back(v);
            }
        }
    }

    for (int k = 1; k < LOG; ++k) {
        for (int v = 1; v <= n; ++v) {
            int mid = up[k - 1][v];
            up[k][v] = mid ? up[k - 1][mid] : 0;
        }
    }

    auto lift = [&](int u, int d) {
        for (int k = 0; k < LOG; ++k) {
            if (d & (1 << k)) u = up[k][u];
        }
        return u;
    };

    auto lca = [&](int u, int v) {
        if (depth[u] < depth[v]) swap(u, v);
        u = lift(u, depth[u] - depth[v]);
        if (u == v) return u;
        for (int k = LOG - 1; k >= 0; --k) {
            if (up[k][u] != up[k][v]) {
                u = up[k][u];
                v = up[k][v];
            }
        }
        return up[0][u];
    };

    string out;
    out.reserve(m * 3);
    for (int i = 0; i < m; ++i) {
        int u, v;
        fin >> u >> v;
        int w = lca(u, v);
        out.append(to_string(w));
        out.push_back('\n');
    }
    fout << out;
    return 0;
}