Cod sursa(job #3348332)

Utilizator andreidebeliiDebelii andreidebelii Data 20 martie 2026 20:24:08
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.47 kb
#include <bits/stdc++.h>

using namespace std;

vector<int> adj[100005];
int depth[100005];
int first[100005];
vector<int> euler;
int st[200010][20];
int logs[200010];

void dfs(int u,int p){
    first[u]=euler.size();
    euler.push_back(u);
    for(int v:adj[u]){
        if(v!=p){
            depth[v]=depth[u]+1;
            dfs(v,u);
            euler.push_back(u);
        }
    }
}
void build_st(){
    int m=euler.size();
    for(int i =0;i<m;i++){
        st[i][0]=euler[i];
    }
    for(int j =1;j<20;j++){
        for(int i =0;i+(1<<j)<=m;i++){
            int left=st[i][j-1];
            int right=st[i+(1<<(j-1))][j-1];
            if(depth[left]<depth[right])st[i][j]=left;
            else st[i][j]=right;
        }
    }
}
int lca(int u,int v){
    int l=first[u],r=first[v];
    if(l>r)swap(l,r);
    int j=logs[r-l+1];
    int left=st[l][j];
    int right=st[r-(1<<j)+1][j];
    if(depth[left]<depth[right])return left;
    return right;
}
int main(){
    ifstream fin("lca.in");
    ofstream fout("lca.out");
    int n,m;
    fin>>n>>m;
    euler.reserve(2*n);
    for(int i=2;i<=n;i++){
        int u;
        fin>>u;
        adj[i].push_back(u);
        adj[u].push_back(i);
    }
    logs[1]=0;
    for(int i =2;i<100005*2;i++)logs[i]=logs[i/2]+1;
    depth[1]=0;
    dfs(1,0);

    build_st();

    for(int i =0;i<m;i++){
        int u,v;
        fin>>u>>v;
        fout<<lca(u,v)<<"\n";
    }
    return 0;
}