Pagini recente » Cod sursa (job #2365389) | Cod sursa (job #2750826) | Cod sursa (job #2464711) | Cod sursa (job #2139711) | Cod sursa (job #2544706)
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;
const int NMAX = 100505;
const int LMAX = (1 << 18);
const int HMAX = (1 << 19);
int N, M;
vector<int> G[NMAX];
int euler[LMAX], firstEuler[NMAX], depth[NMAX], eulerIdx;
int segmentTree[HMAX];
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 buildSegmentTree(int node, int from, int to) {
if (from == to) {
segmentTree[node] = euler[from];
return;
}
int mid = (from + to) / 2;
buildSegmentTree(node * 2, from, mid);
buildSegmentTree(node * 2 + 1, mid + 1, to);
segmentTree[node] = lowerDepth(segmentTree[node * 2], segmentTree[node * 2 + 1]);
}
int query(int node, int from, int to, int queryFrom, int queryTo) {
if (queryTo < from || to < queryFrom) {
return -1;
}
if (queryFrom <= from && to <= queryTo) {
return segmentTree[node];
}
int mid = (from + to) / 2;
int candidateLeft = query(node * 2, from, mid, queryFrom, queryTo);
int candidateRight = query(node * 2 + 1, mid + 1, to, queryFrom, queryTo);
if (candidateLeft == -1 || candidateRight == -1) {
return (candidateLeft == -1) ? candidateRight : candidateLeft;
}
return lowerDepth(candidateLeft, candidateRight);
}
int findNodeLowestDepth(int from, int to) {
if (from > to) {
swap(from, to);
}
return query(1, 1, eulerIdx, from, to);
}
void solve() {
dfs(1);
buildSegmentTree(1, 1, eulerIdx);
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;
}