Cod sursa(job #3314774)

Utilizator Luca_georgescuLuca Georgescu Luca_georgescu Data 11 octombrie 2025 09:12:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.83 kb
#include <bits/stdc++.h>

using namespace std;

ifstream f("lca.in");
ofstream g("lca.out");

const int nmax=1e6+5;
const int inf=2e6+5;

int n,q,euler[2*nmax],k,ind[nmax],h[2*nmax];
int aint[3*nmax+5],m;

vector <int> gr[nmax],v;

bool viz[nmax];

void eulertour(int u, int level, int parent)
{
    viz[u]=1;
    euler[k]=u;
    h[k]=level;

    if ( ind[u]==-1 ) ind[u]=k;

    k++;

    for (auto nod:gr[u] )
    {
        if ( !viz[nod] )
        {
            eulertour(nod,level+1,u);
            euler[k]=u;
            h[k]=level;
            k++;
        }
    }
}

void nxt2(int &n)
{
    while ( n&(n-1) ) n+=(n&-n);
}

void build()
{
    for (int i=0; i<m; i++ )
        aint[i+m]=i;

    for (int i=m-1; i>=1; i-- )
    {
        int l=aint[2*i]; int r=aint[2*i+1];
        if ( h[l]<h[r] ) aint[i]=l;
        else aint[i]=r;
    }
}

int query(int l, int r)
{
    l+=m; r+=m;

    int index=-1;
    while ( l<=r )
    {
        if ( l&1 )
        {
            if ( index==-1 || h[aint[l]]<h[index] )
                index=aint[l];
            l++;
        }
        l>>=1;

        if ( !(r&1) )
        {
            if ( index==-1 || h[aint[r]]<h[index] )
                index=aint[r];
            r--;
        }
        r>>=1;
    }

    return index;
}


int lca(int x, int y)
{
    x=ind[x];
    y=ind[y];

    if ( x>y ) swap(x,y);

    return euler[query(x,y)];
}

int main()
{
    f >> n >> q;

    for (int i=2; i<=n; i++ )
    {
        int x; f >> x;
        gr[x].push_back(i);
        gr[i].push_back(x);
    }

    for (int i=1; i<=n; i++ ) ind[i]=-1;

    eulertour(1,0,0);
    m=k;
    nxt2(m);

    build();

    while ( q-- )
    {
        int x,y;
        f >> x >> y;
        g << lca(x,y) << '\n';
    }
    return 0;
}