Cod sursa(job #3041476)

Utilizator TeodoraMaria123Serban Teodora Maria TeodoraMaria123 Data 31 martie 2023 15:54:40
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.95 kb
#include <bits/stdc++.h>

using namespace std;

#define pb push_back
#define MAX_N 100000

int n, m, L;
vector <int> euler, height, first, lg;
vector <vector <int> > graph;
vector <vector <pair <int, int> > > sp;
bitset <MAX_N + 1> visited;

void dfs(int node, int h)
{
    visited[node] = 1;
    first[node] = euler.size();
    height[node] = h;
    euler.pb(node);

    for(int neighbour : graph[node])
    {
        if(!visited[neighbour])
        {
            dfs(neighbour, h + 1);
            euler.pb(node);
        }
    }
}

void precalculate()
{
    lg.resize(euler.size() + 1);
    lg[1] = 0;
    for(int i = 2; i <= euler.size(); i ++)
        lg[i] = lg[i / 2]  + 1;
}

void sparseTabel()
{
    sp.assign(L + 1, vector <pair <int, int> > (euler.size() + 1));
    for(int i = 0; i < euler.size(); i ++)
    {
        sp[0][i].first = height[euler[i]];
        sp[0][i].second = euler[i];
    }
    for(int i = 1; i <= L; i ++)
        for(int j = 0; j + (1 << i) < euler.size(); j ++)
        {
            sp[i][j] = min(sp[i - 1][j], sp[i - 1][j + (1 << (i - 1))]);
        }
}

int lca(int a, int b)
{
    int l = first[a], r = first[b];
    if(l > r)
        swap(l, r);
    int i = lg[r - l + 1];
    if(sp[i][l].first < sp[i][r - (1 << i) + 1].first)
        return sp[i][l].second;
    return sp[i][r - (1 << i) + 1].second;
}

int main()
{
    ios_base :: sync_with_stdio(0);
    cin.tie(0);

    freopen("lca.in", "r", stdin);
    freopen("lca.out", "w", stdout);

    cin >> n >> m;
    L = ceil(log2(n));
    graph.resize(n + 1);
    for(int i = 2; i <= n; i ++)
    {
        int x;
        cin >> x;
        graph[x].pb(i);
    }

    first.resize(n + 1);
    height.resize(n + 1);

    dfs(1, 1);
    precalculate();
    sparseTabel();

    for(int i = 1; i <= m; i ++)
    {
        int a, b;
        cin >> a >> b;
        cout << lca(a, b) << "\n";
    }
    return 0;
}