Pagini recente » Borderou de evaluare (job #2151096) | Borderou de evaluare (job #2624948) | Cod sursa (job #2095045) | Cod sursa (job #2806908)
#include <bits/stdc++.h>
std::ifstream in("lca.in");
std::ofstream out("lca.out");
template<typename It>
void iter_dbg(It begin, It end) {
for (auto it = begin; it != end; ++it) {
std::clog << *it << " ";
}
std::clog << "\n";
}
template<typename It, typename F>
void iter_dbg_f(It begin, It end, F &&f) {
for (auto it = begin; it != end; ++it) {
std::clog << f(*it, it - begin) << " ";
}
std::clog << "\n";
}
constexpr int N = 1e5 + 1, LOG_2N = 17 + 1;
int n;
std::vector<int> g[N];
int st[LOG_2N][2 * N];
int h[N];
int ep[N];
inline int min_level_node(int u, int v) {
return h[u] < h[v] ? u : v;
}
inline int log2(int x) {
return std::max(0, 31 - __builtin_clz(x));
}
void dfs(int u) {
static int ei;
st[0][++ei] = u;
ep[u] = ei;
for (auto v : g[u])
h[v] = h[u] + 1,
dfs(v),
st[0][++ei] = u;
}
void prepare() {
dfs(1);
int lim = log2(2 * n);
for (int exp = 1; exp <= lim; ++exp)
for (int i = 1; i + (1 << exp) <= 2 * n; ++i)
st[exp][i] = min_level_node(st[exp - 1][i], st[exp - 1][i + (1 << (exp - 1))]);
}
inline int lca(int u, int v) {
int l = ep[u], r = ep[v];
if (l > r)
std::swap(l, r);
int k = log2(r - l + 1);
return min_level_node(st[k][l], st[k][r - (1 << k) + 1]);
}
int main() {
int m;
in >> n >> m;
int u, v;
for (int v = 2; v <= n; ++v)
in >> u,
g[u].push_back(v);
prepare();
for (int i = 0; i < m; ++i)
in >> u >> v,
out << lca(u, v) << "\n";
}