Cod sursa(job #3340170)

Utilizator andrei1232008nicolae andrei andrei1232008 Data 12 februarie 2026 13:46:26
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;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int lim= 1e5+10;
int n,i,Q,m;
int d[lim],aint[16*lim],first[lim];
vector <int> adj[lim];
vector <int> euler_path;

void euler(int k)
{
    euler_path.push_back(k);
    for(auto x:adj[k])
    {
        euler(x);
        euler_path.push_back(k);
    }
}
void dist(int k)
{
    for(auto x:adj[k])
    {
        d[x]=d[k]+1;
        dist(x);
    }
}

int query(int l,int r)
{
    l+=m;
    r+=m;
    int ans=-1;
    while(l<=r)
    {
        if(l%2)
            if(ans==-1||d[ans]>d[aint[l]])ans=aint[l];
        if(!(r%2))
            if(ans==-1||d[ans]>d[aint[r]])ans=aint[r];
        l=(l+1)/2;
        r=(r-1)/2;
    }
    return ans;
}
int main()
{
    fin>>n>>Q;
    for(i=2;i<=n;i++)
    {
        int x;
        fin>>x;
        adj[x].push_back(i);
    }
    dist(1);
    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;
    for(auto x=0;x<m;x++)
        aint[x+m]=euler_path[x];
    for(auto x=m-1;x>0;x--)
        if(d[aint[2*x]]<=d[aint[2*x+1]])
            aint[x]=aint[2*x];
        else aint[x]=aint[2*x+1];
    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;
}