Pagini recente » Cod sursa (job #2504831) | Cod sursa (job #2315631) | Cod sursa (job #1932777) | Cod sursa (job #217908) | Cod sursa (job #1345447)
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
#define NMAX (100001 << 1)
int N, M;
int c_level, pos_rmq = 0;
vector <vector <int> > graph, rmq;
vector <int> level(NMAX), first_found, pow2;
void Euler(int iam, int c_level);
void PrepareRMQ();
int main() {
#ifndef INFOARENA
freopen("input.cpp", "r", stdin);
#else
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
#endif
int i, x, y, px, py, ans, right, dif;
scanf("%d %d", &N, &M);
graph.resize(N + 1);
first_found.resize(N + 1, -1);
rmq.resize(19, vector <int> (NMAX));
for (i = 2; i <= N; ++i) {
scanf("%d", &x);
graph[x].push_back(i);
}
Euler(1, 0);
PrepareRMQ();
for (i = 0; i < M; ++i) {
scanf("%d %d", &x, &y);
px = first_found[x];
py = first_found[y];
if (py < px) {
swap(px, py);
}
dif = py - px + 1;
right = pow2[dif];
ans = rmq[right][px];
if (level[ans] > level[rmq[right][py - (1 << right) + 1]]) {
ans = rmq[right][py - (1 << right) + 1];
}
printf("%d\n", ans);
}
return 0;
}
void Euler(int iam, int c_level) {
rmq[0][pos_rmq] = iam;
level[pos_rmq] = c_level;
first_found[iam] = pos_rmq;
++pos_rmq;
for (auto to: graph[iam]) {
Euler(to, c_level + 1);
rmq[0][pos_rmq] = iam;
level[pos_rmq] = c_level;
++pos_rmq;
}
}
void PrepareRMQ() {
int i, right, k;
pow2.resize(pos_rmq, 0);
for (i = 2; i < pos_rmq; ++i) {
pow2[i] = pow2[i >> 1] + 1;
}
for (k = 1; (1 << k) < pos_rmq; ++k) {
for (i = 0; i + (1 << k) < pos_rmq; ++i) {
rmq[k][i] = rmq[k - 1][i];
right = 1 << (k - 1);
if (level[first_found[rmq[k - 1][i + right]]] < level[first_found[rmq[k][i]]]) {
rmq[k][i] = rmq[k - 1][i + right];
}
}
}
}