Cod sursa(job #3322437)

Utilizator Alexbora13Bora Ioan Alexandru Alexbora13 Data 14 noiembrie 2025 07:45:09
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <bits/stdc++.h>

using namespace std;

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

const int NMAX = 200000;

int n, m, q, x, y;
int parinte[NMAX+1];
vector <int> v[NMAX+1];
pair<int,int> rmq[NMAX+1][31]; int cnt;
int calclog[NMAX+1];
int st[NMAX+1];

void dfs(int nod, int nivel = 1)
{
    rmq[++cnt][0] = make_pair(nod, nivel);
    st[nod] = cnt;
    for(auto a : v[nod])
    {
        dfs(a, nivel+1);
        rmq[++cnt][0] = make_pair(nod, nivel);
    }
}

void calc_rmq()
{
    for(int j=1; j<=30; j++)
    {
        for(int i=1; i<=cnt; i++)
        {
            auto st = rmq[i][j-1];
            if(i + (1<<j) <= cnt)
            {
                auto dr = rmq[i + (1<<(j-1))][j-1];
                rmq[i][j] = st.second < dr.second ? st : dr;
            }
            else rmq[i][j] = st;
        }
    }
}

int lca(int x, int y)
{
    int s = st[x];
    int d = st[y];
    if(s > d)swap(s,d);
    int log = calclog[d-s+1];
    auto st = rmq[s][log];
    auto dr = rmq[d-(1<<log)+1][log];
    return st.second < dr.second ? st.first : dr.first;
}

int main()
{
    fin >> n >> m;
    for(int i=2; i<=n; i++)
    {
        fin >> parinte[i];
        v[parinte[i]].push_back(i);
    }
    dfs(1);
    calc_rmq();
    calclog[1] = 0;
    for(int i=2; i<=cnt; i++)
        calclog[i] = calclog[i/2]+1;
    while(m--)
    {
        fin >> x >> y;
        fout << lca(x, y) << '\n';
    }
    return 0;
}