Cod sursa(job #2989814)

Utilizator Summer05Cocut Alexandru Summer05 Data 7 martie 2023 00:56:23
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.87 kb
#include <bits/stdc++.h>

#pragma GCC optimize("fast-math")

#define ll long long

using namespace std;

int main(void)
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    ios :: sync_with_stdio(false);
    cin.tie(nullptr);

    int n, q;
    cin >> n >> q;
    vector<vector<int>> cv(n + 1);
    for (int i = 2, x; i <= n; i++)
    {
        cin >> x;
        cv[x].push_back(i);
    }
    vector<int> euler(1, 0), level(1, 0);
    vector<int> time_in(n + 1, 0);
    int lvl = -1;
    function<void(int)> dfs = [&](int v)
    {
        ++lvl;
        euler.push_back(v);
        level.push_back(lvl);
        for (int u : cv[v])
        {
            dfs(u);
            euler.push_back(v);
            level.push_back(lvl);
        }
        --lvl;
    };
    dfs(1);
    int m = euler.size() - 1;
    for (int i = 1; i <= m; i++)
        if (time_in[euler[i]] == 0)
            time_in[euler[i]] = i;
    vector<vector<pair<int, int>>> rmq(log2(m) + 1, vector<pair<int, int>>(m + 1, make_pair(0, 0)));
    for (int i = 1; i <= m; i++)
    {
        rmq[0][i].first = level[i];
        rmq[0][i].second = euler[i];
    }
    for (int bit = 1, z = 2; z <= m; bit++, z *= 2)
        for (int j = 1; j + z - 1 <= m; j++)
        {
            rmq[bit][j] = min(rmq[bit - 1][j], rmq[bit - 1][j + z / 2]);
        }
    function<pair<int, int>(int, int)> query = [&](int x, int y)
    {
        int dist = y - x + 1;
        int bit = log2(dist);
        int z = (1 << bit);
        return min(rmq[bit][x], rmq[bit][y - z + 1]);
    };
    function<int(int, int)> LCA = [&](int v, int u)
    {
        return query(min(time_in[v], time_in[u]), max(time_in[v], time_in[u])).second;
    };
    for (int que = 1, v, u; que <= q; que++)
    {
        cin >> v >> u;
        cout << LCA(v, u) << '\n';
    }
    return 0;
}