Cod sursa(job #3339215)

Utilizator Tudor_11Tudor Ioan Calin Tudor_11 Data 7 februarie 2026 09:03:26
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.53 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> v[100001];
vector<int> euler;
vector<int> depth;
int lg[200001];
int rmq[200001][18];
int first[100001];
void dfs(int node,int d)
{
    first[node]=euler.size();
    euler.push_back(node);
    depth.push_back(d);
    for(auto it:v[node])
    {
        dfs(it,d+1);
        euler.push_back(node);
        depth.push_back(d);
    }
}
void build_lg()
{
    for(int i=2;i<=200000;i++)
    {
        lg[i]=lg[i/2]+1;
    }
}
void build_rmq()
{
    for(int i=0;i<euler.size();i++)
    {
        rmq[i][0]=i;
    }
    for(int j=1;(1<<j)<euler.size();j++)
    {
        for(int i=0;i+(1<<j)-1<euler.size();i++)
        {
            int a=rmq[i][j-1];
            int b=rmq[i+(1<<(j-1))][j-1];
            if(depth[a]>depth[b])
            {
                rmq[i][j]=b;
            }
            else rmq[i][j]=a;
        }
    }
}
int lca(int u,int v)
{
    int a=first[u];
    int b=first[v];
    if(a>b) swap(a,b);
    int sz=b-a+1;
    int l=lg[sz];
    int n1=rmq[a][l];
    int n2=rmq[b-(1<<l)+1][l];
    if(depth[n1]>depth[n2]) return euler[n2];
    else return euler[n1];
}
int main()
{
    int n,m;
    fin>>n>>m;
    for(int i=2;i<=n;i++)
    {
        int x;
        fin>>x;
        v[x].push_back(i);
    }
    dfs(1,1);
    build_lg();
    build_rmq();
    for(int i=1;i<=m;i++)
    {
        int u,v;
        fin>>u>>v;
        fout<<lca(u,v)<<'\n';
    }
    return 0;
}