Cod sursa(job #3300593)

Utilizator AndreiNicolaescuEric Paturan AndreiNicolaescu Data 17 iunie 2025 17:46:30
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>
#define cin ci
#define cout co
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int Lmax = 21;
int n, m, x, y;
vector<vector<int>> graf, anc;
vector<int> dist, viz;
void dfs(int node, int par, int h)
{
    dist[node] = h;
    for(auto next:graf[node])
        if(next != par)
            dfs(next, node, h + 1);

}
void binarylifting()
{
    for(int i=1; i<Lmax; i++)
        for(int node=1; node<=n; node++)
            anc[i][node] = anc[i-1][anc[i-1][node]];
}
int findanc(int node, int nmb)
{
    int ans = 0;
    for(int l=Lmax - 1; l>=0; l--)
        if(nmb & (1 << l))
            node = anc[l][node];
    return node;
}
int lca(int node1, int node2)
{
    if(dist[node1] < dist[node2])
        swap(node1, node2);
    node1 = findanc(node1, dist[node1] - dist[node2]);
    if(node1 == node2)
        return node1;
    for(int l=Lmax - 1; l>=0; l--)
        if(anc[l][node1] != anc[l][node2])
        {
            node1 = anc[l][node1];
            node2 = anc[l][node2];
        }
    return anc[0][node1];
}
int main()
{
    cin >> n >> m;
    graf.assign(n+1, vector<int>());
    anc.resize(Lmax, vector<int>(n+1, 0));
    dist.resize(n+1);
    viz.resize(n+1);

    for(int i=2; i<=n; i++)
    {
        cin >> x;
        anc[0][i] = x;
        graf[x].push_back(i);
        graf[i].push_back(x);
    }
    dfs(1, -1, 0);
    for(int i=1; i<=m; i++)
    {
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}