Pagini recente » Cod sursa (job #2474047) | Cod sursa (job #2833769) | Statistici Alina S (allyna) | Cod sursa (job #2024233) | Cod sursa (job #2581279)
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
struct query {
int to, idx;
};
const int NMAX = 100505;
const int LMAX = 2000505;
int N, queries, values[NMAX], from[NMAX], to[NMAX], eulerIdx;
int ans[LMAX];
vector<int> G[NMAX];
vector<query> queryByNode[NMAX];
vector<int> currPath;
void dfs(int node) {
from[node] = ++eulerIdx;
for (auto neighbour : G[node]) {
dfs(neighbour);
}
to[node] = ++eulerIdx;
}
bool inSubtree(int node, int otherNode) {
return from[node] <= from[otherNode] && to[node] >= to[otherNode];
}
int findLca(int otherNode) {
int step = 1;
while (step <= currPath.size()) {
step *= 2;
}
int pos = 0;
for ( ; step; step >>= 1) {
if (pos + step < currPath.size() && inSubtree(currPath[pos + step], otherNode)) {
pos += step;
}
}
return currPath[pos];
}
void dfsQueries(int node) {
currPath.push_back(node);
for (auto neighbour : G[node]) {
dfsQueries(neighbour);
}
for (auto& query : queryByNode[node]) {
ans[query.idx] = findLca(query.to);
}
currPath.pop_back();
}
int main() {
freopen("lca.in", "r", stdin);
froepen("lca.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cin >> N >> queries;
int parent;
for (int node = 2; node <= N; node++) {
cin >> parent;
G[parent].push_back(node);
}
dfs(1);
int x, y;
for (int queryNo = 1; queryNo <= queries; queryNo++) {
cin >> x >> y;
queryByNode[x].push_back({y, queryNo});
}
dfsQueries(1);
for (int queryNo = 1; queryNo <= queries; queryNo++) {
cout << ans[queryNo] << "\n";
}
return 0;
}