Cod sursa(job #2969520)

Utilizator cristiWTCristi Tanase cristiWT Data 23 ianuarie 2023 12:36:31
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.82 kb
#include <bits/stdc++.h>

#include <utility>

#define ll long long

using namespace std;

struct LCA {
    int log, time, n;
    vector<int> tin, tout, depth;
    vector<vector<int>> up, adj;

    void dfs(int nod, int parent, int d) {
        up[nod][0] = parent;
        depth[nod] = d;
        for (int i = 1; i <= log; i++)
            up[nod][i] = up[up[nod][i - 1]][i - 1];

        tin[nod] = ++time;
        for (auto u: adj[nod])
            if (u != parent) dfs(u, nod, d + 1);
        tout[nod] = ++time;
    }

    void init(int sz, vector<vector<int>> aux, int root) {
        n = sz, adj = std::move(aux), time = 0;
        tin = tout = depth = vector<int>(n + 1);
        log = ceil(log2(n));
        up = vector<vector<int>>(n + 1, vector<int>(log + 1));
        dfs(root, root, 0);
    }

    bool ancestor(int u, int v) {
        return tin[u] <= tin[v] && tout[u] >= tout[v];
    }

    int lca(int u, int v) {
        if (ancestor(u, v))
            return u;
        if (ancestor(v, u))
            return v;
        for (int i = log; i >= 0; i--)
            if (!ancestor(up[u][i], v))
                u = up[u][i];
        return up[u][0];
    }

    int dist(int u, int v) {
        return depth[u] + depth[v] - 2 * depth[lca(u, v)];
    }
};

const int NMAX = 1e5 + 10, mod = 1e9 + 7;
int n, q, p[NMAX];
vector<vector<int>> adj;


signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr), cout.tie(nullptr);
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

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

    LCA a;
    a.init(n, adj, 1);
    while (q--) {
        int u, v;
        cin >> u >> v;
        cout << a.lca(u, v) << '\n';
    }
}