Cod sursa(job #3348583)

Utilizator Floroiu_MariusFloroiu Marius Cristian Floroiu_Marius Data 22 martie 2026 19:09:59
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.57 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m;
vector<int> v[100003];
int parent[100003];
int rmq[200003][19];
int depth[100003];
int euler[200003];
int first[100003];
int timer;
void euler_tour(int nod,int tata,int nivel)
{
    timer++;
    first[nod]=timer;
    euler[timer]=nod;
    depth[nod]=nivel;
    for (auto i:v[nod])
    {
        if (i==tata) continue;
        euler_tour(i,nod,nivel+1);
        timer++;
        euler[timer]=nod;
    }
}
int baza[200003];
void precalculare()
{
    baza[1]=0;
    for (int i=2;i<=timer;i++)
        baza[i]=baza[i>>1]+1;
    for (int i=1;i<=timer;i++)
        rmq[i][0]=euler[i];
    for (int j=1;j<=baza[timer];j++)
    {
        for (int i=1;i+(1<<j)-1<=timer;i++)
        {
            int left=rmq[i][j-1];
            int right=rmq[i+(1<<(j-1))][j-1];
            if (depth[left]<=depth[right]) rmq[i][j]=left;
            else rmq[i][j]=right;
        }
    }
}
int lca(int x,int y)
{
    int st=first[x];
    int dr=first[y];
    if (st>dr) swap(st,dr);
    int j=baza[dr-st+1];
    int left=rmq[st][j];
    int right=rmq[dr-(1<<j)+1][j];
    if (depth[left]<=depth[right]) return left;
    return right;
}
int main()
{
    fin>>n>>m;
    for (int i=2;i<=n;i++)
    {
        fin>>parent[i];
        v[parent[i]].push_back(i);
        v[i].push_back(parent[i]);
    }
    euler_tour(1,0,1);
    precalculare();
    while (m--)
    {
        int x,y;
        fin>>x>>y;
        fout<<lca(x,y)<<'\n';
    }
    return 0;
}