Pagini recente » Cod sursa (job #2342706) | Cod sursa (job #70150) | Cod sursa (job #116142) | Cod sursa (job #2576301) | Cod sursa (job #2650286)
#include <bits/stdc++.h>
#define dbg() cerr <<
#define name(x) (#x) << ": " << (x) << ' ' <<
using namespace std;
void Precalc(int node, vector<int> &par, vector<int> &link,
vector<int> &depth, const vector<vector<int>> &adj) {
if (par[node] != -1) {
int p = par[node];
int d1 = depth[p] - depth[link[p]];
int d2 = depth[link[p]] - depth[link[link[p]]];
if (d1 == d2) {
link[node] = link[link[p]];
} else {
link[node] = par[node];
}
} else {
par[node] = node;
link[node] = node;
}
for (auto &x : adj[node]) {
par[x] = node;
depth[x] = 1 + depth[node];
Precalc(x, par, link, depth, adj);
}
}
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q; cin >> n >> q;
vector<vector<int>> adj(n);
vector<int> par(n, -1), link(n, -1), depth(n);
for (int i = 1; i < n; ++i) {
cin >> par[i]; --par[i];
adj[par[i]].emplace_back(i);
}
Precalc(0, par, link, depth, adj);
auto LCA = [&](int a, int b) {
if (depth[a] > depth[b]) swap(a, b);
while (depth[b] > depth[a]) {
if (depth[link[b]] >= depth[a]) b = link[b];
else b = par[b];
}
if (a == b) return a;
assert(depth[a] == depth[b]);
while (a != b) {
if (link[a] != link[b]) {
a = link[a]; b = link[b];
} else {
a = par[a]; b = par[b];
}
}
return a;
};
while (q--) {
int a, b; cin >> a >> b; --a, --b;
cout << 1 + LCA(a, b) << '\n';
}
}