Cod sursa(job #2981711)

Utilizator Elvis_CostinTuca Elvis-Costin Elvis_Costin Data 18 februarie 2023 15:39:03
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.5 kb
#include <bits/stdc++.h>
using namespace std;
string np = "lca";
ifstream f(np + ".in");
ofstream g(np + ".out");

// #define f cin
// #define g cout

int n, m, len, nivel[100003], rmq[20][200009], first[100003];
pair<int, int> w[200003];
vector<int> adj[100003];

void dfs(int nod)
{
    w[++len].first = nod;
    w[len].second = nivel[nod];
    if (!first[nod])
        first[nod] = len;
    for (auto next : adj[nod])
        if (!nivel[next])
            nivel[next] = nivel[nod] + 1, dfs(next),
            w[++len].first = nod, w[len].second = nivel[nod];
}
void build_rmq()
{
    for (int i = 1; i <= len; i++)
        rmq[0][i] = i;
    for (int i = 1, pd = 1; (1 << i) <= len; i++, pd <<= 1)
        for (int j = 1; j + (1 << i) - 1 <= len; j++)
            if (w[rmq[i - 1][j]].second < w[rmq[i - 1][j + pd]].second)
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + pd];
}
int query(int a, int b)
{
    a = first[a];
    b = first[b];
    if (a > b)
        swap(a, b);
    int t = log2(b - a + 1);
    if (w[rmq[t][a]].second < w[rmq[t][b - (1 << t) + 1]].second)
        return w[rmq[t][a]].first;
    return w[rmq[t][b - (1 << t) + 1]].first;
}
int main()
{
    f >> n >> m;
    for (int i = 2, a; i <= n; i++)
        f >> a, adj[a].emplace_back(i), adj[i].emplace_back(a);

    nivel[1] = 1;
    dfs(1);
    build_rmq();

    for (int a, b; m; m--)
        f >> a >> b, g << query(a, b) << '\n';

    return 0;
}