Cod sursa(job #3265317)

Utilizator AndreiNicolaescuEric Paturan AndreiNicolaescu Data 29 decembrie 2024 11:00:34
Problema Lowest Common Ancestor Scor 100
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 = 20;
int n, m, x, y;
vector<vector<int>> anc, graf;
vector<int> viz, d;
void binarylifting()
{
    for(int l=1; l<Lmax; l++)
        for(int node = 1; node <= n; node++)
            anc[l][node] = anc[l-1][anc[l-1][node]];
}
void dfs(int node)
{
    viz[node] = 1;
    for(auto next:graf[node])
        if(!viz[next])
        {
            d[next] = d[node] + 1;
            dfs(next);
        }
}
int findanc(int node, int nanc)
{
    for(int l=0; l<Lmax; l++)
        if(nanc & (1 << l))
            node = anc[l][node];
    return node;
}
int lca(int node1, int node2)
{
    if(d[node1] < d[node2])
        swap(node1, node2);
    node1 = findanc(node1, d[node1] - d[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;
    anc.assign(Lmax + 1, vector<int>(n+1, 0));
    graf.assign(n+1, vector<int>());
    d.resize(n+1);
    viz.resize(n+1);
    for(int i=2; i<=n; i++)
    {
        cin >> anc[0][i];
        graf[anc[0][i]].push_back(i);
        graf[i].push_back(anc[0][i]);
    }
    dfs(1);
    binarylifting();

    while(m--)
    {
        cin >> x >> y;
        cout << lca(x, y) << '\n';
    }
    return 0;
}