Cod sursa(job #2841220)

Utilizator Cosmin2004_InfoMoldoveanu Cosmin Cosmin2004_Info Data 29 ianuarie 2022 13:19:57
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.94 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;
vector <int> tin, r, e;
int n, l, q, u, v, x, y, timer;

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

template <typename T> class RMQ {
    vector <int> lg2; vector <vector <T>> dp;
    int n, h;
    function <T(T, T)> f;
public:
    template <typename Iterator> RMQ(Iterator op, Iterator ed, function <T(T, T)> _f) : n(ed - op), f(_f) {
        h = (31 - __builtin_clz(n));
        lg2.resize(n + 1, 0); dp.resize(h + 1);
        for(int i = 2; i <= n; i++) lg2[i] = lg2[i >> 1] + 1;
        dp[0].resize(n);
        int i = 0;
        for(Iterator it = op; it != ed; it++, i++) dp[0][i] = *it;
        for(int j = 1; j <= h; j++) {
            int jj = (1 << (j - 1)), nj = n - (1 << j);
            dp[j].resize(nj + 1);
            for(int i = 0; i <= nj; i++) dp[j][i] = f(dp[j - 1][i], dp[j - 1][i + jj]);
        }
    }
    T query(int l, int r) { /// indexat de la 0 pe intervalul [l, r)
        if(l > r) swap(l, r);
        int hh = lg2[r - l];
        return f(dp[hh][l], dp[hh][r - (1 << hh)]);
    }
};

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

int main()
{
    //ios_base :: sync_with_stdio(false); cin.tie(nullptr);
    Input();
    dfs(1, 0);
    RMQ <int> rmq(e.begin(), e.end(), [](int a, int b){ return min(a, b); });
    for(int i = 1; i <= q; i++)
        cin >> u >> v,
        cout << r[rmq.query(tin[u], tin[v] + 1)] << "\n";
    return 0;
}