Pagini recente » Cod sursa (job #2169075) | Cod sursa (job #1470846) | Cod sursa (job #2444802) | Cod sursa (job #2567555) | Cod sursa (job #2581258)
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
const int NMAX = 100505;
int N, queries, parent[NMAX];
vector<int> G[NMAX];
int heavyChild[NMAX], depth[NMAX], head[NMAX];
int dfs(int node) {
int currSize = 1, largestChildSize = 0;
for (auto child : G[node]) {
depth[child] = depth[node] + 1;
int childSize = dfs(child);
currSize += childSize;
if (childSize > largestChildSize) {
largestChildSize = childSize;
heavyChild[node] = child;
}
}
return currSize;
}
void createPaths(int node, int startingNode) {
head[node] = node;
if (heavyChild[node] != -1) {
createPaths(heavyChild[node], startingNode);
}
for (auto child : G[node]) {
if (child != heavyChild[node]) {
createPaths(child, child);
}
}
}
int getLca(int x, int y) {
while (head[x] != head[y]) {
if (depth[head[x]] < depth[head[y]]) {
swap(x, y);
}
x = parent[head[x]];
}
return depth[x] < depth[y] ? x : y;
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> queries;
int currParent;
for (int node = 2; node <= N; node++) {
scanf("%d", &currParent);
G[currParent].push_back(node);
parent[node] = currParent;
}
fill(heavyChild, heavyChild + N + 1, -1);
dfs(1);
createPaths(1, 1);
int x, y;
for (int queryNo = 0; queryNo < queries; queryNo++) {
scanf("%d%d", &x, &y);
printf("%d\n", getLca(x, y));
}
return 0;
}