Pagini recente » Cod sursa (job #2660458) | Cod sursa (job #575882) | Cod sursa (job #1980212) | Cod sursa (job #922901) | Cod sursa (job #1977473)
#include <bits/stdc++.h>
using namespace std;
struct HeavyLight {
vector<vector<int>> G;
vector<int> Jump, SubSize, Depth, Lin, Parent;
bool processed;
HeavyLight(int n) :
G(n), Jump(n), SubSize(n), Depth(n), Lin(n), Parent(n) {}
void AddEdge(int a, int b) {
G[a].push_back(b);
G[b].push_back(a);
}
void Preprocess() {
DFSSub(0, -1);
DFSJump(0, 0);
processed = true;
}
int GetLCA(int a, int b) {
assert(processed);
while (Jump[a] != Jump[b]) {
if (Depth[Jump[a]] > Depth[Jump[b]])
a = Parent[Jump[a]];
else
b = Parent[Jump[b]];
}
return Depth[a] > Depth[b] ? b : a;
}
private:
int DFSSub(int node, int par) {
SubSize[node] = 1;
Parent[node] = par;
if (par != -1) {
G[node].erase(find(G[node].begin(), G[node].end(), par));
Depth[node] = 1 + Depth[par];
}
for (auto vec : G[node])
SubSize[node] += DFSSub(vec, node);
return SubSize[node];
}
int timer = 0;
int DFSJump(int node, int jump) {
Jump[node] = jump;
Lin[node] = timer++;
sort(G[node].begin(), G[node].end(), [&](int a, int b) {
return SubSize[a] < SubSize[b];
});
for (auto vec : G[node])
DFSJump(vec, vec == G[node].back() ? jump : vec);
}
};
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
ios_base::sync_with_stdio(false);
cin.tie(0);
int n, m;
cin >> n >> m;
HeavyLight hl(n);
for (int i = 1; i < n; ++i) {
int p;
cin >> p;
hl.AddEdge(p - 1, i);
}
hl.Preprocess();
while (m--) {
int a, b;
cin >> a >> b;
cout << 1 + hl.GetLCA(a - 1, b - 1) << '\n';
}
return 0;
}