Pagini recente » Cod sursa (job #2983664) | Cod sursa (job #2797767) | Cod sursa (job #1741484) | Cod sursa (job #380974) | Cod sursa (job #2803464)
#include <bits/stdc++.h>
std::ifstream in("lca.in");
std::ofstream out("lca.out");
constexpr int N = 1e5, M = 2e6, LOG_N = 13;
int n;
std::vector<int> g[N];
std::pair<int, int> pairs[M];
int ancest[LOG_N + 1][N];
int depth[N];
void find_levels() {
std::function<void(int, int)> dfs = [&](int u, int level) {
depth[u] = level;
for (int v : g[u]) {
if (depth[v] == 0) {
dfs(v, level + 1);
}
}
};
dfs(0, 1);
}
void build_ancest() {
std::function<void(int, int)> dfs = [&](int u, int above) {
ancest[0][u] = above;
for (int exp = 1; exp <= LOG_N; ++exp) {
ancest[exp][u] = ancest[exp - 1][ancest[exp - 1][u]];
}
for (int v : g[u]) {
if (v != above) {
dfs(v, u);
}
}
};
dfs(0, 0);
}
void raise(int &u, int levels) {
for (int exp = 0; exp <= LOG_N; ++exp) {
if (levels & (1 << exp)) {
u = ancest[exp][u];
}
}
}
int lca(int u, int v) {
if (depth[u] < depth[v]) {
std::swap(u, v);
}
raise(u, depth[u] - depth[v]);
if (u == v) {
return u;
}
for (int exp = LOG_N; exp >= 0; --exp) {
if (ancest[exp][u] != ancest[exp][v]) {
u = ancest[exp][u];
v = ancest[exp][v];
}
}
return ancest[0][u];
}
int main() {
int m;
in >> n >> m;
for (int i = 0; i < n - 1; ++i) {
int u;
in >> u;
--u;
g[u].push_back(i + 1);
g[i + 1].push_back(u);
}
find_levels();
build_ancest();
for (int i = 0; i < m; ++i) {
int u, v;
in >> u >> v;
--u;
--v;
out << lca(u, v) + 1 << "\n";
}
}