Cod sursa(job #3175693)

Utilizator andiRTanasescu Andrei-Rares andiR Data 26 noiembrie 2023 12:43:13
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.31 kb
//https://www.infoarena.ro/problema/lca
#include <iostream>
#include <fstream>
#include <vector>

#pragma GCC optimize ("O3")

#define pb push_back

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

const int Nmax = 1e5+5;

int n, m, h[Nmax];
vector<int> ad[Nmax];
vector<int> st[Nmax];

inline void dfs(int nod, int p){
    h[nod]=h[p]+1;

    st[nod].pb(p);
    int pow=2, ind=0;
    while (pow<=h[nod]){
        st[nod].pb(st[st[nod][ind]][ind]);
        pow*=2; ind++;
    }

    for (auto it:ad[nod])
        if (it!=p)
            dfs(it, nod);
}
int binary_lift(int nod, int lvl){
    if (lvl==0)
        return nod;
    int ind=0, p=1;
    while (p*2<=lvl){
        p*=2; ind++;
    }
    return binary_lift(st[nod][ind], lvl-p);
}
int lca(int a, int b){
    if (h[a]<h[b])
        swap(a, b);
    a=binary_lift(a, h[a]-h[b]);
    if (a==b)
        return a;
    for (int i=st[a].size()-1; i>=0; i--)
        if (st[a][i]!=st[b][i]){
            a=st[a][i];
            b=st[b][i];
         }
    return st[a][0];
}

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);
    }

    h[0]=-1;
    dfs(0, 0);

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