Cod sursa(job #3229258)

Utilizator AlexPlesescuAlexPlesescu AlexPlesescu Data 14 mai 2024 20:55:12
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>

using namespace std;
#define pb push_back
const int N = 100005;

int in[N], depth[N], e[2 * N], rmq[18][2 * N], LOGMAX, n, q, m, timer = 1;
vector<int> g[N], euler_tour;

void dfs(int node, int parinte, int h) {
    in[node] = euler_tour.size();
    depth[node] = h;
    euler_tour.pb(node);
    for (auto vec : g[node]) {
        if (vec != parinte) {
            dfs(vec, node, h + 1);
            euler_tour.pb(node);
        }
    }
}

int get_min(int st, int dr) {
    int lg = e[dr - st + 1];
    if (depth[rmq[lg][st]] <= depth[rmq[lg][dr - (1 << lg) + 1]])
        return rmq[lg][st];
    return rmq[lg][dr - (1 << lg) + 1];
}

int lca(int u, int v) {
    if (in[u] > in[v])
        swap(u, v);
    return get_min(in[u], in[v]);
}

int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);
    cin.tie(0)->sync_with_stdio(0);
    cin >> n >> m;
    for (int i = 1; i < n; i++) {
        int a;
        cin >> a;
        g[a].pb(i + 1);
        g[i + 1].pb(a);
    }
    euler_tour.pb(-1);
    dfs(1, 0, 0);
    int sz = euler_tour.size();
    sz--;
    e[1] = 0;
    for (int i = 2; i <= sz; i++)
        e[i] = e[i / 2] + 1;
    for (int i = 1; i <= sz; i++)
        rmq[0][i] = euler_tour[i];
    for (int i = 1; (1 << i) <= sz; i++) {
        for (int j = 1; j <= sz; j++) {
            rmq[i][j] = rmq[i - 1][j];
            if (j + (1 << i) - 1 <= sz && depth[rmq[i - 1][j]] > depth[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
        }
    }
    while (m--) {
        int u, v;
        cin >> u >> v;
        cout << lca(u, v) << '\n';
    }
    return 0;
}