Cod sursa(job #2930817)

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

using namespace std;

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

using bleat = pair <int, int>;

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

bleat 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];
    bleat val1 = r[e][dr];
    bleat val2 = r[e][st + (1 << e) - 1];
    if (val1.first < val2.first)cout << val1.second << '\n';
    else cout << val2.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)
        {
            bleat val1 = r[i - 1][j];
            bleat val2 = r[i - 1][j - (1 << (i - 1))];
            r[i][j] = (val1.first < val2.first) ? val1 : val2;
        }
    while (q-- && cin >> x >> y)
        lcaquery(x, y);
    return 0;
}