Cod sursa(job #3206827)

Utilizator raresOObreja Rares raresO Data 24 februarie 2024 11:20:51
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.2 kb
#include <fstream>
#include <iostream>
#include <vector>

#define NMAX 100'007
#define LOG 20

std::ofstream cout("lca.out");
std::ifstream cin("lca.in");
int n, m;
std::vector<int> G[NMAX];
int up[NMAX][40], tin[NMAX], tout[NMAX], timp = 0;

void citire()
{
    cin >> n >> m;
    int a;
    for (int i = 1; i < n; i++)
    {
        cin >> a;
        G[a].push_back(i + 1);
    }
}

void dfs(int nod, int tata)
{
    tin[nod] = ++timp;

    up[nod][0] = tata;
    for (int j = 1; j <= LOG; j++)
    {
        up[nod][j] = up[up[nod][j - 1]][j - 1];
    }

    for (auto it : G[nod])
    {
        if (it != tata)
            dfs(it, nod);
    }
    tout[nod] = ++timp;
}

bool is_anc(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; }

int lca(int a, int b)
{
    if (is_anc(a, b))
        return a;
    if (is_anc(b, a))
        return b;
    for (int i = LOG; i >= 0; i--)
    {
        if (!is_anc(up[a][i], b))
            a = up[a][i];
    }
    return up[a][0];
}

int main()
{
    citire();
    dfs(1, 1);
    int u, v;
    for (int i = 1; i <= m; i++)
    {
        cin >> u >> v;
        cout << lca(u, v) << '\n';
    }
    return 0;
}