Pagini recente » Cod sursa (job #2516383) | Cod sursa (job #1230113) | Cod sursa (job #888415) | Cod sursa (job #3127765) | Cod sursa (job #1349717)
#include <cstdio>
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
#define NMAX (100000 << 1)
int N, M, pos_euler = 1;
vector <int> euler_nodes(NMAX), level(NMAX), biggest_power2, first_found(NMAX);
vector <vector <int> > rmq, graph;
void EulerDfs(int iam, int c_level);
void PrepareRMQ();
int main() {
#ifdef INFOARENA
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
#else
freopen("input.cpp", "r", stdin);
#endif
int i, x, y, lg, p2, px, py, ans;
scanf("%d %d", &N, &M);
graph.resize(N + 1);
for (i = 2; i <= N; ++i) {
scanf("%d", &x);
graph[x].push_back(i);
}
EulerDfs(1, 0);
PrepareRMQ();
for (i = 1; i <= M; ++i) {
scanf("%d %d", &x, &y);
px = first_found[x];
py = first_found[y];
if (py < px) {
swap(px, py);
}
lg = py - px + 1;
p2 = biggest_power2[lg];
ans = rmq[p2][px];
if (level[rmq[p2][py - (1 << p2) + 1]] < level[ans]) {
ans = rmq[p2][py - (1 << p2) + 1];
}
printf("%d\n", euler_nodes[ans]);
}
return 0;
}
void EulerDfs(int iam, int c_level) {
euler_nodes[pos_euler] = iam;
level[pos_euler] = c_level;
first_found[iam] = pos_euler;
++pos_euler;
for (auto to: graph[iam]) {
EulerDfs(to, c_level + 1);
euler_nodes[pos_euler] = iam;
level[pos_euler] = c_level;
++pos_euler;
}
}
void PrepareRMQ() {
biggest_power2.resize(pos_euler, 0);
rmq.resize(19, vector <int> (pos_euler, 0));
--pos_euler;
int i, k, lg;
rmq[0][1] = 1;
for (i = 2; i <= pos_euler; ++i) {
biggest_power2[i] = biggest_power2[i >> 1] + 1;
rmq[0][i] = i;
}
for (k = 1; (1 << k) <= pos_euler; ++k) {
lg = 1 << (k - 1);
for (i = 1; i + (1 << k) - 1 <= pos_euler; ++i) {
rmq[k][i] = rmq[k - 1][i];
if (level[rmq[k - 1][i + lg]] < level[rmq[k][i]]) {
rmq[k][i] = rmq[k - 1][i + lg];
}
}
}
}