Pagini recente » Cod sursa (job #2802880) | Cod sursa (job #2439328) | Cod sursa (job #520895) | Cod sursa (job #2156633) | Cod sursa (job #1742306)
#include <bits/stdc++.h>
#define NMAX 100001
#define MAXLOG 17
#define minn(a, b) a < b ? a : b
#define pb push_back
using namespace std;
int N, M, p[NMAX], euler[10 * NMAX], level[NMAX], first[NMAX], rmq[10 * NMAX][MAXLOG], x, y, tmp;
vector<int> graph[NMAX];
void buildEuler(int node, int currLevel) {
euler[++euler[0]] = node;
if (first[node] == 0) {
level[node] = currLevel;
first[node] = euler[0];
}
for(vector<int>::iterator it = graph[node].begin(); it < graph[node].end(); ++it) {
buildEuler(*it, currLevel + 1);
euler[++euler[0]] = node;
}
}
void buildRMQ() {
for (int it = 0; it < euler[0]; ++it) {
rmq[it][0] = it + 1;
}
for (int j = 1; (1 << j) <= euler[0]; ++j) {
for (int i = 0; i + (1 << j) - 1 < euler[0]; ++i) {
if (euler[rmq[i][j - 1]] < euler[rmq[i + (1 << (j - 1))][j - 1]]) {
rmq[i][j] = rmq[i][j - 1];
} else {
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
}
}
}
int queryRMQ(int left, int right) {
int k = (int) log2(right - left + 1);
return minn(euler[rmq[left][k]], euler[rmq[right - (1 << k) + 1][k]]);
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &N, &M);
for (int it = 2; it <= N; ++it) {
scanf("%d", p + it);
graph[p[it]].pb(it);
}
buildEuler(1, 0);
//for (int it = 1; it <= euler[0]; ++it) printf("%d ", euler[it]);
//printf("\n");
//for (int it = 1; it <= euler[0]; ++it) printf("%d ", first[it]);
//printf("\n");
buildRMQ();
for (int it = 0; it < M; ++it) {
scanf("%d%d", &x, &y);
//printf("%d %d ", first[x], first[y]);
if (first[x] > first[y]) {
tmp = x; x = y; y = tmp;
}
printf("%d\n", queryRMQ(first[x] - 1, first[y] - 1));
}
return 0;
}