Cod sursa(job #3003439)

Utilizator 100pCiornei Stefan 100p Data 15 martie 2023 18:52:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.7 kb
#include <bits/stdc++.h>

#define MAX 100000
#define FILES freopen("lca.in","r",stdin);\
              freopen("lca.out","w",stdout);
#define mod 666013

using namespace std;

int n, m, depth[MAX + 5], f[MAX + 5];

vector<int> v[MAX + 5];
vector<pair<int,int>> euler, rmq[24];

bool check[MAX + 5];

void dfs(int x, int d)
{
    check[x] = 1;
    depth[x] = d;
    euler.push_back({x, depth[x]});
    f[x] = euler.size() - 1;
    for(auto i : v[x])
    {
        if(!check[i])
        {
            dfs(i, d + 1);
            euler.push_back({x, depth[x]});
        }
    }
}

pair<int,int> ff(pair<int,int> a, pair<int,int> b)
{
    return (a.second < b.second ? a : b);
}

pair<int,int> findLca(int a, int b)
{
    int mn = min(f[a], f[b]), mx = max(f[a], f[b]), d = mx - mn + 1;
    int p = 1,e = 0;
    while(p * 2 < d)
        p *= 2, e++;
    return ff(rmq[e][mn], rmq[e][mx - p + 1]);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);
    FILES
    std::cin >> n >> m;
    for(int i = 1;i < n; ++i)
    {
        int a;
        std::cin >> a;
        v[a].push_back(i + 1);
        v[i + 1].push_back(a);
    }
    dfs(1, 1);
    for(int i = 0;i < euler.size(); ++i)
        rmq[0].push_back(euler[i]);
    int p = log2(euler.size()), sz = euler.size();
    for(int i = 1;i <= p; ++i)
    {
        sz -= (1 << (i - 1));
        for(int j = 1;j <= sz; ++j)
            rmq[i].push_back(ff(rmq[i - 1][j - 1], rmq[i - 1][j - 1 + (1 << (i - 1))]));
    }
    for(int i = 1;i <= m; ++i)
    {
        int a, b;
        std::cin >> a >> b;
        pair<int,int> rez = findLca(a, b);
        std::cout << rez.first << '\n';
    }
}