Cod sursa(job #2841177)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 29 ianuarie 2022 12:58:41
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.4 kb
#include <bits/stdc++.h>

using namespace std;
#ifdef INFOARENA
#define cin fin
#define cout fout
ifstream fin("lca.in");
ofstream fout("lca.out");
#endif // INFOARENA
vector <vector <int>> g, e;
vector <int> tin, r, lg2;
int n, l, q, u, v, x, y, timer;

void dfs(int v, int p)
{
    tin[v] = ++timer;
    r[timer] = v;
    e[0][timer] = timer;
    for(int u : g[v])
        if(u != p)
            dfs(u, v);
    e[0][++timer] = tin[p];
}

void Input() {
    cin >> n >> q; g.resize(n + 1); tin.resize(n + 1); r.resize(2 * n + 1); timer = 0; lg2.resize(2 * n + 1);
    l = floor(log2(n)) + 1;
    e.resize(l + 1);
    for(int i = 0; i <= l; i++) e[i].resize(2 * n - (1 << i) + 2);
    for(int i = 2; i <= n; i++)
        cin >> x,
        g[i].push_back(x),
        g[x].push_back(i);
}

int lca(int a, int b) {
    a = tin[a], b = tin[b];
    int lg = lg2[b - a + 1];
    return r[min(e[lg][a], e[lg][b - (1 << lg) + 1])];
}

int main()
{
    //ios_base :: sync_with_stdio(false); cin.tie(nullptr);
    Input();
    dfs(1, 0);
    for(int i = 2; i <= 2 * n; i++) lg2[i] = lg2[i >> 1] + 1;
    for(int j = 1; j <= l; j++) {
        int sz = 1 << j;
        for(int i = 1; i <= timer - sz + 1; i++)
            e[j][i] = min(e[j - 1][i], e[j - 1][i + (sz >> 1)]);
    }
    for(int i = 1; i <= q; i++)
        cin >> u >> v,
        cout << lca(u, v) << "\n";
    return 0;
}