Pagini recente » Cod sursa (job #2539434) | Cod sursa (job #890582) | Cod sursa (job #889629) | Cod sursa (job #2666212) | Cod sursa (job #2170547)
#include <bits/stdc++.h>
using namespace std;
const int nmax = static_cast<int> (2 * (1e5+1));
const int lgnmax = 19;
int n, m;
int dp[lgnmax][nmax];
inline int pow2(int x) {
return (1 << x);
}
int lg2[nmax];
void precalc_lg2() {
lg2[0] = 1;
for (int i = 2; i <= n; i++) {
lg2[i] = lg2[i / 2] + 1;
}
}
vector<int> graph[nmax];
int level[nmax];
int first[nmax];
int euler_cnt;
void euler_df(int node, int clevel) {
level[node] = clevel;
dp[0][++euler_cnt] = node;
first[node] = euler_cnt;
for (auto &next_node: graph[node]) {
euler_df(next_node, clevel + 1);
dp[0][++euler_cnt] = node;
}
}
void build_rmq() {
precalc_lg2();
for (int i = 1; i <= lg2[n]; i++) {
for (int j = 1; j <= n - pow2(i) + 1; j++) {
if (level[dp[i - 1][j]] < level[dp[i - 1][j + pow2(i - 1)]]) {
dp[i][j] = dp[i - 1][j];
} else {
dp[i][j] = dp[i - 1][j + pow2(i - 1)];
}
}
}
}
int query(int x, int y) {
x = first[x];
y = first[y];
if (x > y) swap(x, y);
int k = lg2[y - x + 1];
if (level[dp[k][x]] < level[dp[k][y - pow2(k) + 1]]) {
return dp[k][x];
}
return dp[k][y - pow2(k) + 1];
}
int main() {
freopen("carici.in", "r", stdin);
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &n, &m);
for (int i = 1, x; i < n; i++) {
scanf("%d", &x);
graph[x].push_back(i + 1);
}
euler_df(1, 0);
n = euler_cnt;
build_rmq();
for (int i = 0, x, y; i < m; i++) {
scanf("%d%d", &x, &y);
cout << query(x, y) << "\n";
}
return 0;
}