Cod sursa(job #3334737)

Utilizator alexdraguAlexandru Dragu alexdragu Data 19 ianuarie 2026 13:31:55
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.23 kb
#include <fstream>
#include <vector>
#define lim 100005
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector<int> v[lim];
int n,q,x,y,i,h[lim*2],ceva[lim*2],first[lim],lg[lim*2],rmq[20][lim*2],k;
void dfs(int nod,int timer)
{
    h[++k]=nod;
    ceva[k]=timer;
    first[nod]=k;
    for(auto x:v[nod])
    {
        dfs(x,timer+1);
        h[++k]=nod;
        ceva[k]=timer;
    }
}
void rmq2()
{
    for(int i=2;i<=k;i++) lg[i]=lg[i/2]+1;
    for(int i=1;i<=k;i++) rmq[0][i]=i;
    for(int i=1;(1<<i)<k;i++)
    {
        for(int j=1;j<=k-(1<<i);j++)
        {
            int l=1<<(i-1);
            rmq[i][j]=rmq[i-1][j];
            if(ceva[rmq[i-1][j+l]]<ceva[rmq[i][j]]) rmq[i][j]=rmq[i-1][j+l];
        }
    }
}
int lca(int x,int y)
{
    int a=first[x],b=first[y],dif,l,sol,sh;
    if(a>b) swap(a,b);
    dif=b-a+1;
    l=lg[dif];
    sol=rmq[l][a];
    sh=dif-(1<<l);
    if(ceva[sol]>ceva[rmq[l][a+sh]]) sol=rmq[l][a+sh];
    return h[sol];
}
int main()
{
    cin>>n>>q;
    for(i=2;i<=n;i++)
    {
        cin>>x;
        v[x].push_back(i);
    }
    dfs(1,0);
    rmq2();
    while(q--)
    {
        cin>>x>>y;
        cout<<lca(x,y)<<'\n';
    }
    return 0;
}