Cod sursa(job #3041281)

Utilizator VladS23Vlad Seba VladS23 Data 31 martie 2023 11:03:30
Problema Lowest Common Ancestor Scor 30
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.84 kb
#include <fstream>
#include <vector>
#include <cmath>

using namespace std;

ifstream cin("lca.in");
ofstream cout("lca.out");

const int NMAX = 1e5;

int n, m;
int K;
int euler[NMAX + 5], lvl[NMAX + 5], first[NMAX + 5], rmq[NMAX + 5][20];

vector<vector<int>> edges;

void dfs(int node, int depth)
{
    euler[++K] = node;
    lvl[K] = depth; 
    first[node] = K;

    for (auto it : edges[node])
    {
        dfs(it, depth + 1);
        euler[++K] = node;
        lvl[K] = depth;
    }
}

void preprocess()
{
    for (int i = 1; i <= K; i++)
        rmq[i][0] = i;

    for (int j = 1; (1 << j) <= K; j++)
    {
        for (int i = 1; i + (1 << j) - 1 <= K; i++)
        {
            if (lvl[rmq[i][j - 1]] > lvl[rmq[i + (1 << (j - 1))][j - 1]])
                rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
            else
                rmq[i][j] = rmq[i][j - 1];
        }
    }
}

int query(int l, int r)
{
    int aux = log2(r - l + 1);
    if (lvl[rmq[l][aux]] < lvl[rmq[r - (1 << aux) + 1][aux]])
        return rmq[l][aux];
    else
        return rmq[r - (1 << aux) + 1][aux];
}

int lca(int a, int b)
{
    int st = first[a], dr = first[b];
    if (st > dr)
        swap(st, dr);

    int aux = query(st, dr);
    return euler[aux];
}

int main()
{
    cin >> n >> m;
    edges.resize(n + 1);
    for (int i = 2; i <= n; i++)
    {
        int x;
        cin >> x;
        edges[x].push_back(i);

    }
    dfs(1, 0);
    // for (int i = 1; i <= K; i++)
    // {
    //     cout << euler[i] << " \n"[i == K];
    // }
    // for (int i = 1; i <= K; i++)
    // {
    //     cout << lvl[i] << " \n"[i == K];
    // }

    preprocess();

    for (int i = 1; i <= m; i++)
    {
        int a, b;
        cin >> a >> b;
        cout << lca(a, b) << '\n';
    }
    return 0;
}