Cod sursa(job #3142485)

Utilizator radu._.21Radu Pelea radu._.21 Data 21 iulie 2023 21:54:35
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.31 kb
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,first[100001],v[200001],E[100001];
struct abc{
    int nod; int lvl;
}rmq[20][200001];
int k=0;
vector<int>G[100001];
void dfs(int nod,int lvl = 1){
    rmq[0][++k]={nod,lvl};
    first[nod]=k;
    for(int fiu : G[nod]){
        dfs(fiu,lvl+1);
        rmq[0][++k]={nod,lvl};
    }
}
void precalculare(){
    E[1]=0;
    for(int i=2;i<=k;i++)
        E[i]=E[i/2]+1;
}
void Rmq(){
    for(int p=1;(1<<p)<=k;p++)
    for(int i=1;i<=k;i++){
        rmq[p][i]=rmq[p-1][i];
        int j= i + (1<<(p-1));
        if(j<=k && rmq[p][i].lvl>rmq[p-1][j].lvl)
            rmq[p][i]=rmq[p-1][j];
    }

}
int lca(int x,int y){
    int poz1=first[x];
    int poz2=first[y];
    if(poz1>poz2)
        swap(poz1,poz2);
    int pow=E[poz2-poz1+1];
    abc st = rmq[pow][poz1];
    abc dr =  rmq[pow][poz2-(1<<pow)+1];
    if(st.lvl<dr.lvl)
        return st.nod;
    else
        return dr.nod;
}
int main(){
    fin>>n>>m;
    for(int i=2;i<=n;i++){
        int parinte;
        fin>>parinte;
        G[parinte].push_back(i);
    }
    dfs(1);
    precalculare();
    Rmq();
    while(m--){
        int x,y;
        fin>>x>>y;
        fout<<lca(x,y)<<'\n';
    }
    return 0;
}