Cod sursa(job #3175992)

Utilizator andiRTanasescu Andrei-Rares andiR Data 26 noiembrie 2023 16:42:58
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.39 kb
#include <iostream>
#include <fstream>
#include <vector>

#define pb push_back
#define fi first
#define se second

using namespace std;

ifstream fin("lca.in");
ofstream fout("lca.out");

typedef pair<int, int> pii;

const int Nmax=1e5+5;

int n, m, f[Nmax];
vector<int> ad[Nmax], lg;
vector<pii> euler, st[20];

void dfs(int nod, int p, int h){
    f[nod]=euler.size();
    euler.pb({h, nod});

    for (auto it:ad[nod])
        if (it!=p){
            dfs(it, nod, h+1);
            euler.pb({h, nod});
        }
}
inline void build_sparse_table(){
    for (int i=0; i<euler.size(); i++)
        st[0].pb(euler[i]);

    int p=2, ind=1;
    while (p<=euler.size()){
        for (int i=0; i+p<=euler.size(); i++)
            st[ind].pb(min(st[ind-1][i], st[ind-1][i+p/2]));
        p*=2; ind++;
    }
}
inline void build_lg(){
    lg.resize(euler.size()+1);
    lg[1]=0;
    for (int i=2; i<=euler.size(); i++)
        lg[i]=lg[i/2]+1;
}
int lca(int x, int y){
    if (f[x]>f[y]) swap(x, y);
    int lg2=lg[f[y]-f[x]+1];
    return min(st[lg2][f[x]], st[lg2][f[y]-(1<<lg2)+1]).se;
}
int main(){
    fin>>n>>m;

    int nr;
    for (int i=1; i<n; i++){
        fin>>nr; nr--;
        ad[i].pb(nr);
        ad[nr].pb(i);
    }

    dfs(0, -1, 0);
    build_sparse_table();
    build_lg();

    int x, y;
    for (int i=1; i<=m; i++){
        fin>>x>>y;
        x--; y--;
        fout<<lca(x, y)+1<<'\n';
    }
    return 0;
}