Pagini recente » Cod sursa (job #802168) | Cod sursa (job #2902094) | Cod sursa (job #233318) | Cod sursa (job #442909) | Cod sursa (job #2051985)
#include <bits/stdc++.h>
using namespace std;
template<typename T>
struct RMQ {
int n;
vector<vector<T>> mem;
vector<int> log;
void Build(vector<T> V) {
n = V.size();
log.resize(n + 1);
log[1] = 0;
for (int i = 2; i <= n; ++i)
log[i] = 1 + log[i / 2];
mem.emplace_back(move(V));
for (int it = 1; mem.back().size() > 1; ++it) {
vector<T> nwmem;
int step = (1 << it), lim = mem.back().size();
for (int i = 0, j = step / 2; j < lim; ++i, ++j)
nwmem.push_back(min(mem.back()[i], mem.back()[j]));
mem.emplace_back(move(nwmem));
}
}
T Query(int a, int b) {
int i = log[b - a];
return min(mem[i][a], mem[i][b - (1 << i)]);
}
};
struct LCA {
vector<int> enter, depth;
vector<vector<int>> G;
vector<pair<int, int>> linear;
RMQ<pair<int, int>> rmq;
int timer = 0;
LCA(int n) : enter(n, -1), depth(n), G(n), linear(2 * n) {}
void dfs(int node, int dep) {
linear[timer] = {dep, node};
enter[node] = timer++;
depth[node] = dep;
for (auto vec : G[node])
if (enter[vec] == -1) {
dfs(vec, dep + 1);
linear[timer++] = {dep, node};
}
}
void AddEdge(int a, int b) {
G[a].push_back(b);
G[b].push_back(a);
}
void Build(int root) {
dfs(root, 0);
rmq.Build(linear);
}
int Query(int a, int b) {
a = enter[a], b = enter[b];
return rmq.Query(min(a, b), max(a, b) + 1).second;
}
int Distance(int a, int b) {
return depth[a] + depth[b] - 2 * depth[Query(a, b)];
}
};
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, m; cin >> n >> m;
LCA lca(n);
for (int i = 1; i < n; ++i) {
int par; cin >> par;
lca.AddEdge(par - 1, i);
}
lca.Build(0);
while (m--) {
int a, b; cin >> a >> b;
cout << 1 + lca.Query(a - 1, b - 1) << '\n';
}
return 0;
}