Cod sursa(job #3151582)

Utilizator TeddyDinutaDinuta Eduard Stefan TeddyDinuta Data 21 septembrie 2023 21:20:05
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.49 kb
#include <bits/stdc++.h>

using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
int n, m, x, y, k, p[100005], d[200005][30];
vector<int> adj[100005];
vector<pair<int, int>> t;

void preorder(int nod, int lvl) {
    t.push_back({lvl, nod});
    p[nod] = t.size() - 1;
    for (auto it : adj[nod]) {
        preorder(it, lvl + 1);
        t.push_back({lvl, nod});
    }
}

int logg(int x) {
    int ans = 0;
    while ((1 << (ans + 1)) <= x)
        ans++;

    return ans;
}

int main()
{
    in >> n >> m;
    for (int i = 2; i <= n; i++) {
        in >> x;
        adj[x].push_back(i);
    }

    t.push_back({-1, -1});
    preorder(1, 0);

    int k = t.size() - 1;

    for (int i = 1; i <= k; i++)
        d[i][0] = i;

    for (int i = 1; (1 << i) <= k; i++)
        for (int j = 1; j + (1 << i) - 1 <= k; j++) {
            d[j][i] = d[j][i - 1];
            if (t[d[j + (1 << (i - 1))][i - 1]].first < t[d[j][i]].first) {
                d[j][i] = d[j + (1 << (i - 1))][i - 1];
            }
        }

    while (m--) {
        in >> x >> y;
        int st = min(p[x], p[y]);
        int dr = max(p[x], p[y]);


        int l = dr - st + 1;
        int lg = logg(l);
        int dif = l - (1 << lg);

        int pos = 0;
        if (t[d[st][lg]].first < t[d[st + dif][lg]].first) {
            pos = d[st][lg];
        } else {
            pos = d[st + dif][lg];
        }
        out << t[pos].second << '\n';
    }

    return 0;
}