Cod sursa(job #2930816)

Utilizator _andrei4567Stan Andrei _andrei4567 Data 29 octombrie 2022 17:19:37
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.62 kb
#include <fstream>
#include <vector>
#include <bitset>
#include <math.h>

using namespace std;

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

const int N = 2e5 + 1;
int l[N + 1], h[N + 1], euler[N + 1], prim[N + 1], lg[N + 1];

pair <int, int> r[19][N + 1];

vector <int> g[N + 1];

bitset <N + 1> viz;

int n, q, x, y, k;

void dfs (int node)
{
    viz[node] = 1;
    euler[++k] = node;
    for (auto it : g[node])
        if (!viz[it])l[it] = l[node] + 1, dfs(it), euler[++k] = node;
}

void lcaquery (int x, int y)
{
    int st = min (prim[x], prim[y]), dr = max (prim[x], prim[y]);
    int e = lg[dr - st + 1];
    int val1 = r[e][dr].first;
    int val2 = r[e][st + (1 << e) - 1].first;
    if (val1 < val2)cout << r[e][dr].second << '\n';
    else cout << r[e][st + (1 << e) - 1].second << '\n';
}

int main()
{
    cin >> n >> q;
    for (int i = 1; i < n && cin >> x; ++i)
        g[x].push_back(i + 1);
    dfs (1);
    for (int i = 2; i <= k; ++i)
        lg[i] = 1 + lg[i >> 1];
    for (int i = 1; i <= k; ++i)
    {
        h[i] = l[euler[i]];
        r[0][i] = {h[i], euler[i]};
        if (!prim[euler[i]])prim[euler[i]] = i;
    }
    for (int i = 1; i <= lg[k]; ++i)
        for (int j = 1; j <= k; ++j)
        {
            int val1 = r[i - 1][j].first;
            int val2 = r[i - 1][j - (1 << (i - 1))].first;
            if (val1 <= val2)
                r[i][j] = {val1, r[i - 1][j].second};
            else
                r[i][j] = {val2, r[i - 1][j - (1 << (i - 1))].second};
        }
    while (q-- && cin >> x >> y)
        lcaquery(x, y);
    return 0;
}