Cod sursa(job #3313622)

Utilizator Luca_georgescuLuca Georgescu Luca_georgescu Data 5 octombrie 2025 15:47:15
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.68 kb
#include <bits/stdc++.h>

using namespace std;

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

const int nmax=1e6+5;

int n,q,euler[2*nmax],k,ind[nmax],h[nmax];
int t[4*nmax];

vector <int> gr[nmax];

bool viz[nmax];

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

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


void init(int nod, int st, int dr)
{
    if ( st==dr )
    {
        t[nod]=st;
        return;
    }

    int mid=(st+dr)/2;

    init(2*nod,st,mid);
    init(2*nod+1,mid+1,dr);

    if ( h[t[2*nod]]>h[t[2*nod+1]] )
        t[nod]=t[2*nod+1];
    else t[nod]=t[2*nod];
}

int query(int nod, int st, int dr, int p, int q)
{
    if ( st>=p && dr<=q )
        return t[nod];

    int cl=-1;
    int cr=-1;

    int mid=(st+dr)/2;

    if ( mid>=p )
        cl=query(2*nod,st,mid,p,q);

    if ( mid+1<=q )
        cr=query(2*nod+1,mid+1,dr,p,q);

    if ( cl==-1 ) return cr;
    if ( cr==-1 ) return cl;

    if ( h[cl]<h[cr] )
        return cl;
    else return cr;
}

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

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

    return euler[query(1,1,k,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);
    }

    eulertour(1,1,1);
    init(1,1,k);

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