Cod sursa(job #3002567)

Utilizator MocalinnoMoca Andrei Catalin Mocalinno Data 14 martie 2023 21:25:00
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.46 kb
#include <bits/stdc++.h>
#define FUG fin.close(); fout.close(); exit(0);
using namespace std;

string const& task("lca");
ifstream fin((task + ".in").c_str());
ofstream fout((task + ".out").c_str());

int const N(1e5 + 5), LN(17);
int dad[LN][N], l2[N], p2[LN], n, m, lvl[N];
vector<int> g[N];

inline void Init() {
    for (int i = 2; i < N; ++i)
        l2[i] = l2[i / 2] + 1;
    p2[0] = 1;
    for (int i = 1; i < LN; ++i)
        p2[i] = p2[i - 1] * 2;
}

inline void DFS(int const& x = 1) {
    for (int l = 1; l < LN; ++l) {
        dad[l][x] = dad[l - 1][dad[l - 1][x]];
        if (!dad[l][x]) break;
    }
    for (int const& y : g[x]) {
        dad[0][y] = x;
        lvl[y] = lvl[x] + 1;
        DFS(y);
    }
}

inline int LCA(int const& a, int const& b) {
    int x = a, y = b;
    if (lvl[x] < lvl[y])
        swap(x, y);
    for (int l = l2[lvl[x] - lvl[y] + 1]; l >= 0; --l)
        if (lvl[x] - p2[l] >= lvl[y])
            x = dad[l][x];
    if (x == y) return x;
    for (int l = l2[lvl[x] + 1]; l >= 0; --l)
        if (dad[l][x] != dad[l][y]) {
            x = dad[l][x];
            y = dad[l][y];
        }
    return dad[0][x];
}

signed main() {

    Init();
    fin >> n >> m;
    for (int i = 2; i <= n; ++i) {
        int x;
        fin >> x;
        g[x].emplace_back(i);
    }
    DFS();
    while (m--) {
        int x, y;
        fin >> x >> y;
        fout << LCA(x, y) << '\n';
    }

    FUG
}