Cod sursa(job #3318388)

Utilizator calinarulMarinescu Calin calinarul Data 28 octombrie 2025 12:15:45
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.23 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int NMAX=1e5+5;
vector<int>adj[NMAX];
bitset<NMAX>vizitat;
int first[NMAX];
int lg[4*NMAX];
vector<pair<int,int>>euler;
pair<int,int> dp[20][4*NMAX];
void dfs(int nod,int nivel,int parinte)
{
    first[nod]=euler.size();
    euler.push_back({nivel,nod});
    for(int i:adj[nod])
    {
        if(i!=parinte){
        dfs(i,nivel+1,nod);
        euler.push_back({nivel,nod});
        }
    }
}
void rmq()
{
    // euler.push_back({0,0});
    dfs(1,0,0);
    dp[0][0]=euler[0];
    dp[0][1]=euler[1];
    for(int i=2;i<euler.size();i++){
    lg[i]=lg[i/2]+1;
    dp[0][i]=euler[i];
    }
    for(int k=1;(1<<k)<=euler.size();k++)
    {
        for(int i=0;i+(1<<k)<=euler.size();i++)
        dp[k][i]=min(dp[k-1][i],dp[k-1][i+(1<<(k-1))]);
    }
}
int query(int l,int r)
{
    if(l>r)swap(l,r);
    int k=lg[r-l+1];
    return min(dp[k][l],dp[k][r-(1<<k)+1]).second;
}
int main()
{
    int n,q;
    fin>>n>>q;
    for(int i=2;i<=n;i++)
    {
        int u;
        fin>>u;
        adj[i].push_back(u);
        adj[u].push_back(i);
    }
    rmq();
    while(q--)
    {
        int x,y;
        fin>>x>>y;
        fout<<query(first[x],first[y])<<'\n'; 
    }
}