Pagini recente » Cod sursa (job #952380) | Cod sursa (job #2960786) | Cod sursa (job #1953336) | Cod sursa (job #2202598) | Cod sursa (job #2844825)
#include <bits/stdc++.h>
using namespace std;
using Graph = vector<vector<int>>;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N = 200000 + 5;
int n, q, parent[N], depth[N], pos[N], m;
int lg[2 * N], rmq[20][2 * N];
vector<int> euler(1);
Graph adj(N);
int minDepth(int x, int y) {
return (depth[x] < depth[y] ? x : y);
}
void dsfEuler(int u, int dep) {
euler.emplace_back(u);
depth[u] = dep + 1;
pos[u] = (int)euler.size() - 1;
for (const auto& v : adj[u]) {
dsfEuler(v, dep + 1);
euler.emplace_back(u);
}
}
void buildRmq() {
lg[1] = 0;
for (int i = 2; i < 2 * N; ++i)
lg[i] = lg[i / 2] + 1;
for (int i = 1; i <= m; ++i)
rmq[0][i] = euler[i];
for (int i = 1; i <= lg[m] + 1; ++i) {
for (int j = 1; j + (1 << (i-1)) <= m; ++j) {
rmq[i][j] = minDepth(rmq[i - 1][j], rmq[i - 1][j + (1 << (i-1))]);
}
}
}
int queryRmq(int l, int r) {
int k = lg[r - l + 1];
return minDepth(rmq[k][l], rmq[k][r - (1 << k) + 1]);
}
int lca(int x, int y) {
return queryRmq(min(pos[x], pos[y]), max(pos[x], pos[y]));
}
int main() {
ios_base::sync_with_stdio(false);
fin.tie(nullptr);
fout.tie(nullptr);
fin >> n >> q;
for (int i = 2; i <= n; ++i) {
int u, w;
fin >> u ;
parent[i] = u;
adj[u].emplace_back(i);
}
dsfEuler(1, 0);
m = euler.size() - 1;
buildRmq();
while (q--) {
int u, v;
fin >> u >> v;
fout << lca(u, v) << '\n';
}
}