Cod sursa(job #3311121)

Utilizator parrot279Sofi Tudose parrot279 Data 19 septembrie 2025 17:39:21
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.65 kb
#include <bits/stdc++.h>

using namespace std;

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

void dfs(int nod, int nivel);
void precalc();
int lca(int st, int dr);

int n, m, euler_size;
vector<pair<int, int>> euler;
vector<int> copii[100002];
pair<int, int> rmq[400002][20]; //.first = nivel, .second = nod
int first[100002], lg2[400002];
bool apare[100002];

int main()
{
    fin>>n>>m;
    for(int i = 1; i <= n-1; ++i)
    {
        int nod;
        fin>>nod;
        copii[nod].push_back(i+1);
    }
    dfs(1, 0);
    precalc();

    for(int i = 1; i <= m; ++i)
    {
        int x, y;
        fin>>x>>y;
        x = first[x];
        y = first[y];
        if(x > y)
            swap(x, y);
        fout<<lca(x, y)<<"\n";
    }
    return 0;
}

int lca(int st, int dr)
{
    int l = lg2[dr - st + 1];
    pair<int, int> rez = min(rmq[st][l], rmq[dr - (1<<l) + 1][l]);
    return rez.second;
}

void precalc()
{
    for(int i = 2; i <= euler_size; ++i)
        lg2[i] = lg2[i/2] + 1;

    for(int i = 0; i < euler_size; ++i)
        rmq[i][0] = {euler[i].first, euler[i].second};

    for(int i = 1; (1<<i) < euler_size; ++i)
    {
        for(int j = 0; j + (1<<i) <= euler_size; ++j)
        {
            rmq[j][i] = min(rmq[j][i-1], rmq[(1<<(i-1)) + j][i-1]);
        }
    }


}


void dfs(int nod, int nivel)
{
    ++euler_size;
    euler.push_back({nivel, nod});
    if(!apare[nod])
    {
        apare[nod] = true;
        first[nod] = euler_size - 1;
    }
    for(auto i : copii[nod])
    {
        dfs(i, nivel+1);
        ++euler_size;
        euler.push_back({nivel, nod});
    }
}