Pagini recente » Cod sursa (job #1602106) | Cod sursa (job #1464827) | Cod sursa (job #914791) | Cod sursa (job #1112949) | Cod sursa (job #2544713)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
const int NMAX = 100505;
const int LMAX = (1 << 18);
const int LGMAX = 19;
int N, M;
vector<int> G[NMAX];
int euler[LMAX], firstEuler[NMAX], depth[NMAX], eulerIdx;
int lg[LMAX], lowestDepthRange[LGMAX][LMAX];
bool visited[NMAX];
void read() {
cin >> N >> M;
int x;
for (int node = 2; node <= N; node++) {
cin >> x;
G[x].push_back(node);
G[node].push_back(x);
}
}
void dfs(int node) {
visited[node] = true;
euler[++eulerIdx] = node;
firstEuler[node] = eulerIdx;
for (auto neighbour : G[node]) {
if (!visited[neighbour]) {
depth[neighbour] = depth[node] + 1;
dfs(neighbour);
euler[++eulerIdx] = node;
}
}
}
inline int lowerDepth(int node1, int node2) {
return depth[node1] < depth[node2] ? node1 : node2;
}
void buildRMQ() {
for (int i = 2; i <= eulerIdx; i++) {
lg[i] = lg[i >> 1] + 1;
}
for (int posEuler = 1; posEuler <= eulerIdx; posEuler++) {
lowestDepthRange[0][posEuler] = euler[posEuler];
}
for (int pow2Idx = 1; (1 << pow2Idx) <= eulerIdx; pow2Idx++) {
int currentLength = 1 << pow2Idx;
int prevLength = 1 << (pow2Idx - 1);
for (int start = 1; start <= eulerIdx - currentLength + 1; start++) {
lowestDepthRange[pow2Idx][start] = lowerDepth(
lowestDepthRange[pow2Idx - 1][start], lowestDepthRange[pow2Idx - 1][start + prevLength]);
}
}
}
int findNodeLowestDepth(int from, int to) {
if (from > to) {
swap(from, to);
}
int pow2Idx = lg[to - from + 1];
return lowerDepth(
lowestDepthRange[pow2Idx][from], lowestDepthRange[pow2Idx][to - (1 << pow2Idx) + 1]);
}
void solve() {
dfs(1);
buildRMQ();
int x, y;
for (int queryIdx = 0; queryIdx < M; queryIdx++) {
cin >> x >> y;
cout << findNodeLowestDepth(firstEuler[x], firstEuler[y]) << "\n";
}
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(NULL);
read();
solve();
return 0;
}