Pagini recente » Cod sursa (job #1517633) | Cod sursa (job #639317) | Cod sursa (job #748617) | Cod sursa (job #1050801) | Cod sursa (job #2080432)
#include <bits/stdc++.h>
using namespace std;
constexpr int DIM = 400005;
vector< int > sons[DIM];
int rmq[21][DIM], counter, first_app[DIM], level[DIM];
int pow2[DIM];
void dfs(int node) {
rmq[0][counter++] = node;
first_app[node] = counter - 1;
for (auto&& it : sons[node]) {
level[it] = level[node] + 1;
dfs(it);
rmq[0][counter++] = node;
}
}
void compute_rmq() {
for (int i = 1; (1 << i) <= counter; ++i) {
for (int j = 0; j < counter; ++j) {
rmq[i][j] = rmq[i - 1][j];
if (j + (1 << (i-1)) < counter
&& level[rmq[i - 1][j + (1 << (i-1))]] < level[rmq[i - 1][j]])
rmq[i][j] = rmq[i - 1][j + (1 << (i-1))];
}
}
}
void precompute_powers_of_2() {
pow2[1] = 0;
for (int i = 2; i <= counter; ++i)
pow2[i] = pow2[i / 2] + 1;
}
int lca(int first, int second) {
first = first_app[first];
second = first_app[second];
if (first > second)
swap(first, second);
int pow = pow2[second - first + 1];
if (level[ rmq[pow][first] ] < level[ rmq[pow][second - (1 << pow) + 1] ])
return rmq[pow][first];
else
return rmq[pow][second - (1 << pow) + 1];
}
void solve() {
int node_count, query_count;
cin >> node_count >> query_count;
for (int i = 2; i <= node_count; ++i) {
int p;
cin >> p;
sons[p].push_back(i);
}
counter = 0;
dfs(1);
precompute_powers_of_2();
compute_rmq();
while (query_count--) {
int first, second;
cin >> first >> second;
cout << lca(first, second) << '\n';
}
}
int main() {
assert(freopen("lca.in", "r", stdin));
assert(freopen("lca.out", "w", stdout));
cin.tie(nullptr);
ios_base::sync_with_stdio(false);
solve();
return 0;
}