Cod sursa(job #3340226)

Utilizator andrei1232008nicolae andrei andrei1232008 Data 12 februarie 2026 21:43:32
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int lim=1e5+10;
vector <int> euler_path;
vector <int> v[lim];
int n,i,t[lim],Q,d[lim],first[lim],aint[16*lim],m;
void euler(int k)
{
    euler_path.push_back(k);
    for(auto x:v[k])
    {
        euler(x);
        euler_path.push_back(k);
    }
}
void dist(int k)
{
    for(auto x:v[k])
    {
        d[x]=d[k]+1;
        dist(x);
    }
}

int query(int l,int r)
{
    l+=m;
    r+=m;
    int res=0;
    while(l<=r)
    {
        if(l%2)
            if(d[aint[l]]<d[res])
                res=aint[l];
        if(!(r%2))
            if(d[aint[r]]<d[res])
                res=aint[r];
        l=(l+1)/2;
        r=(r-1)/2;
    }
    return res;
}
int main()
{
    fin>>n>>Q;
    for(i=2;i<=n;i++)
    {
        int x;
        fin>>x;
        t[i]=x;
        v[x].push_back(i);
    }
    euler(1);
    m=euler_path.size();
    for(i=1;i<=n;i++)
        first[i]=-1;
    for(auto x=0;x<m;x++)
        if(first[euler_path[x]]==-1)first[euler_path[x]]=x;
    dist(1);
    for(i=0;i<m;i++)
        aint[i+m]=euler_path[i];
    for(i=m-1;i>0;i--)
    {
        if(d[aint[2*i]]<d[aint[2*i+1]])
            aint[i]=aint[2*i];
        else aint[i]=aint[2*i+1];
    }
    d[0]=1e9;
    while(Q--)
    {
        int l,r;
        fin>>l>>r;
        l=first[l];
        r=first[r];
        if(l>r)swap(l,r);
        fout<<query(l,r)<<'\n';
    }
    return 0;
}