Pagini recente » Cod sursa (job #626031) | Cod sursa (job #884364) | Cod sursa (job #1562548) | Cod sursa (job #1283200) | Cod sursa (job #3277484)
#include <bits/stdc++.h>
using namespace std;
int n, q;
vector<int> v[100001], depth;
int depthNode[200001], last[100001];
int rmq[200001][19], logn[200001];
void eulerDfs(int node, int node_depth) {
depth.push_back(node_depth);
depthNode[depth.size() - 1] = node;
last[node] = depth.size() - 1;
for (int i = 0; i < v[node].size(); ++i) {
eulerDfs(v[node][i], node_depth + 1);
depth.push_back(node_depth);
depthNode[depth.size() - 1] = node;
last[node] = depth.size() - 1;
}
}
bool comp(int x, int y) {
return depth[x] < depth[y];
}
int lca(int x, int y) {
int t1 = min(last[x], last[y]);
int t2 = max(last[x], last[y]);
int maxLog = logn[t2 - t1 + 1];
int ans = min(rmq[t1][maxLog], rmq[t2 - (1 << maxLog) + 1][maxLog], comp);
return depthNode[ans];
}
void calcRmq() {
logn[2] = 1;
for (int i = 3; i <= depth.size(); ++i) {
logn[i] = logn[i / 2] + 1;
}
for (int i = 0; i < depth.size(); ++i) {
rmq[i][0] = i;
}
for (int p = 1; p <= logn[depth.size()]; ++p) {
for (int i = 0; i + (1 << p) - 1 < depth.size(); ++i) {
rmq[i][p] = min(rmq[i][p - 1], rmq[i + (1 << (p - 1))][p - 1], comp);
}
}
}
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
cin >> n >> q;
for (int i = 2; i <= n; ++i) {
int father;
cin >> father;
v[father].push_back(i);
}
eulerDfs(1, 0);
calcRmq();
for (int i = 1; i <= q; ++i) {
int x, y;
cin >> x >> y;
cout << lca(x, y) << "\n";
}
}