Cod sursa(job #3350328)

Utilizator CarenaMironov Cezar Luca Carena Data 7 aprilie 2026 12:06:44
Problema Lowest Common Ancestor Scor 50
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.29 kb
#include <fstream>
#include <vector>
#define fr first
#define sc second

using namespace std;

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

const int NMAX=1e5+5, LMAX=16;
int n, m, dtime, p[NMAX], d[NMAX], poz[NMAX];
vector<int> adj[NMAX];

void tle()
{
    while(true)
        m++;
}

struct RMQ
{
    int rmq[LMAX+1][2*NMAX];
    
    void build()
    {
        for(int b=1;b<=LMAX;b++)
            for(int i=1;i+(1<<b)-1<=dtime;i++)
                if(d[rmq[b-1][i]]<d[rmq[b-1][i+(1<<(b-1))]])
                    rmq[b][i]=rmq[b-1][i];
                else
                    rmq[b][i]=rmq[b-1][i+(1<<(b-1))];
    }
    
    int query(int l, int r)
    {
        if(l>r)
            swap(l, r);
        int lg=31-__builtin_clz(r-l+1);
        if(d[rmq[lg][l]]<d[rmq[lg][r-(1<<lg)+1]])
            return rmq[lg][l];
        return rmq[lg][r-(1<<lg)+1];
    }
}ds;

void DFS(int u)
{
    if(u>n)
        tle();
    ds.rmq[0][++dtime]=u;
    poz[u]=dtime;
    for(auto v:adj[u])
    {
        d[v]=d[u]+1;
        DFS(v);
        ds.rmq[0][++dtime]=u;
    }
}

int main()
{
    in>>n>>m;
    for(int i=2;i<=n;i++)
    {
        in>>p[i];
        adj[p[i]].push_back(i);
    }
    DFS(1);
    ds.build();
    while(m--)
    {
        int u, v; in>>u>>v;
        out<<ds.query(poz[u], poz[v])<<'\n';
    }
    return 0;
}