Cod sursa(job #2939530)

Utilizator 100pCiornei Stefan 100p Data 13 noiembrie 2022 21:02:44
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.48 kb
#include <bits/stdc++.h>
#define FILES freopen("lca.in","r",stdin);\
              freopen("lca.out","w",stdout);
#define MAX 100000
using namespace std;
int n, q, x, f[MAX + 5];
bool check[MAX + 5];
vector<int> v[MAX + 5];
vector<pair<int,int>> euler, rmq[MAX + 5];
void dfs(int x, int d)
{
    check[x] = 1;
    euler.push_back({x, d});
    f[x] = euler.size() - 1;
    for(auto i : v[x])
    {
        if(!check[i])
        {
            dfs(i, d + 1);
            euler.push_back({x , d});
        }
    }
}
pair<int,int> Min(pair<int,int> a, pair<int,int> b)
{
    return (a.second > b.second ? b : a);
}
pair<int,int> GetLca(int i,int j)
{
    int d = j - i + 1, p = 1, e = 0;
    while(p <= d)
        p <<= 1, e++;
    p >>= 1, e--;
    return Min(rmq[e][i], rmq[e][j - p + 1]);
}
int main()
{
    FILES
    cin >> n >> q;
    for(int i = 1;i < n; ++i)
    {
        cin >> x;
        v[i + 1].push_back(x), v[x].push_back(i + 1);
    }
    dfs(1, 0);
    for(int i = 0;i < euler.size(); ++i)
        rmq[0].push_back(euler[i]);
    int cnt = euler.size(), p = log2(cnt);
    for(int i = 1;i <= p; ++i)
    {
        cnt -= (1 << (i - 1));
        for(int j = 1;j <= cnt; ++j)
            rmq[i].push_back(Min(rmq[i - 1][j - 1], rmq[i - 1][j + (1 << (i - 1)) - 1]));
    }
    while(q--)
    {
        int a, b;
        cin >> a >> b;
        pair<int,int> ans = GetLca(min(f[a], f[b]), max(f[a], f[b]));
        cout << ans.first << '\n';
    }
}