Pagini recente » Cod sursa (job #814102) | Cod sursa (job #565803) | Cod sursa (job #1093609) | Cod sursa (job #914826) | Cod sursa (job #2546582)
#include <cstdio>
#include <vector>
using namespace std;
const int NMAX = 100505;
const int LMAX = 18;
int N, M, startEuler[NMAX], finishEuler[NMAX], eulerIdx;
int parent[LMAX][NMAX], lg[NMAX];
vector<int> G[NMAX];
void read() {
scanf("%d%d", &N, &M);
for (int node = 2; node <= N; node++) {
scanf("%d", &parent[0][node]);
G[parent[0][node]].push_back(node);
}
}
void dfs(int node) {
startEuler[node] = ++eulerIdx;
for (auto& neighbour : G[node]) {
dfs(neighbour);
}
finishEuler[node] = ++eulerIdx;
}
void binaryLifting() {
for (int depth = 2; depth <= N; depth++) {
lg[depth] = lg[depth >> 1] + 1;
}
for (int powIdx = 1; (1 << powIdx) <= N; powIdx++) {
for (int node = 1; node <= N; node++) {
parent[powIdx][node] = parent[powIdx - 1][parent[powIdx - 1][node]];
}
}
}
inline bool isNode2AncestorOf(int node1, int node2) {
return startEuler[node1] <= startEuler[node2] && finishEuler[node2] <= finishEuler[node1];
}
int findLca(int node1, int node2) {
if (isNode2AncestorOf(node1, node2)) {
return node1;
}
for (int depth = lg[N]; depth >= 0; depth--) {
if (!isNode2AncestorOf(parent[depth][node1], node2)) {
node1 = parent[depth][node1];
}
}
return parent[0][node1];
}
void solve() {
dfs(1);
startEuler[0] = 0; finishEuler[0] = eulerIdx + 1;
binaryLifting();
int x, y;
for (int query = 0; query < M; query++) {
scanf("%d%d", &x, &y);
printf("%d\n", findLca(x, y));
}
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
read();
solve();
return 0;
}