Cod sursa(job #3282539)

Utilizator CimpoesuFabianCimpoesu Fabian George CimpoesuFabian Data 5 martie 2025 21:00:50
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.58 kb
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");

int n, m, poz[100001], e[17], rmq[17][100001];
vector<int> G[100001], euler, level;

void EulerTour(int nod, int lvl)
{
    euler.push_back(nod);
    level.push_back(lvl);
    if (poz[nod] == -1) poz[nod] = euler.size() - 1;
    for (auto next : G[nod])
    {
        EulerTour(next, lvl + 1);
        euler.push_back(nod);
        level.push_back(lvl);
    }
}

void BuildRMQ()
{
    int i, j;
    e[1] = 0;
    for (i = 2; i < euler.size(); i++)
        e[i] = e[i / 2] + 1;
    for (i = 0; i < euler.size(); i++)
        rmq[0][i] = i;
    for (i = 1; i <= e[euler.size() - 1]; i++)
        for (j = 0; j + (1 << i) <= euler.size(); j++)
            if (level[rmq[i - 1][j]] < level[rmq[i - 1][j + (1 << (i - 1))]])
                rmq[i][j] = rmq[i - 1][j];
            else
                rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}

int main()
{
    int i, x, y, k, len;
    for (i = 0; i <= 100000; i++)
        poz[i] = -1;
    fin >> n >> m;
    for (i = 2; i <= n; i++)
    {
        fin >> x;
        G[x].push_back(i);
    }
    EulerTour(1, 1);
    BuildRMQ();
    for (i = 1; i <= m; i++)
    {
        fin >> x >> y;
        x = poz[x];
        y = poz[y];
        if (x > y) swap(x, y);
        len = y - x + 1;
        k = e[len];
        if (level[rmq[k][x]] < level[rmq[k][y - (1 << k) + 1]])
            fout << euler[rmq[k][x]] << "\n";
        else
            fout << euler[rmq[k][y - (1 << k) + 1]] << "\n";
    }
    return 0;
}