Pagini recente » Cod sursa (job #2612723) | Cod sursa (job #592781) | Cod sursa (job #2234422) | Cod sursa (job #2754017) | Cod sursa (job #2661455)
#include <cstdio>
#include <vector>
using namespace std;
#define MAXN 100004
int k, n;
int first[MAXN], levels[MAXN * 2], euler[MAXN * 2], logs[MAXN << 1];
int rmq[20][MAXN << 2];
vector<vector<int>> arcs;
void get_levels(int node, int level) {
levels[++k] = level;
euler[k] = node;
first[node] = k;
for(int i=0; i<arcs[node].size(); ++i) {
get_levels(arcs[node][i], level + 1);
levels[++k] = level;
euler [k] = node;
}
}
void compute_rmq() {
for(int i=2; i<=k; ++i)
logs[i] = logs [i / 2] + 1;
for(int i=0; i<=k; ++i)
rmq[0][i] = i;
for(int i=1; (1<<i) < k; ++i)
for(int j=1; j <= k - (1<<i); ++j) {
int leftover = 1 << (i-1);
rmq[i][j] = rmq[i-1][j];
if (levels[rmq[i-1][j + leftover]] < levels[rmq[i][j]])
rmq[i][j] = rmq[i-1][j+leftover];
}
}
int query(int x, int y) {
int diff;
int left, right;
if (first[x] < first[y]) {
left = first[x];
right = first[y];
} else {
left = first[y];
right = first[x];
}
diff = right - left + 1;
int sol = rmq[logs[diff]][left];
int leftover = diff - (1<< logs[diff]);
if (levels[sol] > levels[rmq[logs[diff]][left + leftover]])
sol = rmq[logs[diff]][left + leftover];
return euler[sol];
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int m, x, y;
scanf("%d%d", &n, &m);
arcs.resize(n+2);
for(int i=2; i<=n; ++i) {
scanf("%d", &x);
arcs[x].push_back(i);
}
get_levels(1, 0);
compute_rmq();
for(int i=0; i<m; ++i) {
scanf("%d%d", &x, &y);
printf("%d\n", query(x, y));
}
return 0;
}