Pagini recente » Cod sursa (job #1631350) | Cod sursa (job #2071302) | Cod sursa (job #1240428) | Cod sursa (job #1741924) | Cod sursa (job #2700331)
#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int>>;
int lg(int n) { return 31 - __builtin_clz(n); }
struct RMQ {
vector<vector<int>> rmq;
RMQ(const vector<int>& v) : rmq(1 + lg(v.size()), v) {
for (int i = 0; i + 1 < (int)rmq.size(); ++i)
for (int j = 0; j + (2 << i) <= (int)v.size(); ++j)
rmq[i + 1][j] = min(rmq[i][j], rmq[i][j + (1 << i)]);
}
int Query(int a, int b) {
assert(a < b); int dep = lg(b - a);
return min(rmq[dep][a], rmq[dep][b - (1 << dep)]);
}
};
struct LCA {
int n, timer = 0;
vector<int> enter, lv, lt;
RMQ rmq;
LCA(Graph& graph, int root = 0) :
n(graph.size()), enter(n, -1),
rmq((dfs(graph, root), lt)) {}
void dfs(Graph& graph, int node) {
enter[node] = timer++;
for (auto vec : graph[node]) {
if (enter[vec] != -1) continue;
lv.push_back(node), lt.push_back(enter[node]);
dfs(graph, vec);
}
}
int Query(int a, int b) {
if (a == b) return a;
a = enter[a], b = enter[b];
return lv[rmq.Query(min(a, b), max(a, b))];
}
// Distance is depth[a] + depth[b] - 2 depth[Query(a, b)]
};
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q; cin >> n >> q;
Graph graph(n);
for (int i = 1; i < n; ++i) {
int p; cin >> p; graph[p - 1].push_back(i);
}
LCA L(graph);
for (int i = 0; i < q; ++i) {
int a, b; cin >> a >> b;
cout << L.Query(a - 1, b - 1) + 1 << '\n';
}
return 0;
}