Cod sursa(job #3213926)

Utilizator Alex_DumitrascuAlex Dumitrascu Alex_Dumitrascu Data 13 martie 2024 16:56:25
Problema Lowest Common Ancestor Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.35 kb
#include <iostream>
#include <vector>
#include <cstdio>
using namespace std;
int tata [24][100005];
vector <int> g[100005];
int level[100005];
int n, m;
int Log2[100005];
void dfs (int nod)
{
    for (int vecin : g[nod]) {
        level[vecin]=level[nod]+1;
        dfs(vecin);
    }
}
void precalculate()
{
    for (int i=2; i<=n; i++) {
        Log2[i]=Log2[i/2]+1;
    }
    for (int i=1; (1<<i)<=n; i++) {
        for (int j=1; j<=n; j++) {
            tata[i][j]=tata[i-1][tata[i-1][j]];
        }
    }
}
int solve (int a, int b) ///a va avea cel mai mare nivel
{
    while (level[a]!=level[b]) {
        int k=Log2[level[a]-level[b]];
        a=tata[k][a];
    }
    if (a==b) return a;
    for (int i=Log2[level[a]]; i>=0; i--) {
        if (tata[i][a]!=tata[i][b]) {
            a=tata[i][a];
            b=tata[i][b];
        } else break;
    }
    return tata[0][a];
}
int main()
{
    freopen("lca.in", "r", stdin);
    freopen("lca.out","w",stdout);
    cin.tie(0);
    cin.sync_with_stdio(false);
    cout.tie(0);
    cout.sync_with_stdio(false);
    cin>>n>>m;
    for (int i=2; i<=n; i++) {
        cin>>tata[0][i];
        g[tata[0][i]].push_back(i);
    }
    dfs(1);
    precalculate();
    int a, b;
    for (int i=1; i<=m; i++) {
        cin>>a>>b;
        if (level[a]<level[b]) swap(a, b);
        int x=solve(a, b);
        cout<<x<<'\n';
    }
    return 0;
}