Cod sursa(job #3343880)

Utilizator andrei_nAndrei Nicolae andrei_n Data 28 februarie 2026 17:48:00
Problema Lowest Common Ancestor Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.98 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");

int n, m;
vector <int> g[200001];

int rmq[20][200001]; //indicele minimului in tour pe [j, j + 2 ^ i - 1]
int lg2[200001];

int tour[200001], toursize;
int h[200001];
int tin[200001], tout[200001]; //pozitia in tour in care node intra/iese

void dfs_tour(int node, int parent)
{
    tour[++toursize] = node;
    h[node] = h[parent] + 1;
    for (auto vecin : g[node])
        if (vecin != parent)
        {
            dfs_tour(vecin, node);
            tour[++toursize] = node;
        }
}

void calc_tin(int node, int parent)
{
    for (int t = 1; t <= toursize; t++)
    {
        if (!tin[tour[t]])
            tin[tour[t]] = t;
        tout[tour[t]] = t;
    }
}

void calc_rmq()
{
    for (int j = 1; j <= toursize; j++)
        rmq[0][j] = j;

    lg2[1] = 0;
    for (int i = 2; i <= 100000; i++)
        lg2[i] = lg2[i / 2] + 1;

    for (int i = 1; i <= 19; i++)
        for (int j = 1; j <= (toursize - (1 << i)) + 1; j++)
            if (h[tour[rmq[i - 1][j + (1 << (i - 1))]]] < h[tour[rmq[i - 1][j]]])
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
            else
                rmq[i][j] = rmq[i - 1][j];
}

int query(int l, int r)
{
    int lung = r - l + 1;
    int p = lg2[lung];

    if (h[tour[rmq[p][l]]] < h[tour[rmq[p][r - (1 << p) + 1]]])
        return tour[rmq[p][l]];
    else
        return tour[rmq[p][r - (1 << p) + 1]];
}

int main()
{
    fin >> n >> m;

    for (int i = 1; i <= n - 1; i++)
    {
        int node;
        fin >> node;
        g[i + 1].push_back(node);
        g[node].push_back(i + 1);
    }

    h[0] = -1;
    dfs_tour(1, 0);
    calc_tin(1, 0);

    calc_rmq();

    for (int i = 1; i <= m; i++)
    {
        int x, y;
        fin >> x >> y;
        if (tin[x] > tin[y])
            swap(x, y);

        fout << query(tin[x], tin[y]) << '\n';
    }
    return 0;
}