Pagini recente » Cod sursa (job #2257859) | Cod sursa (job #1150194) | Cod sursa (job #188103) | Cod sursa (job #2136581) | Cod sursa (job #1977511)
#include <bits/stdc++.h>
using namespace std;
struct LCASolver {
vector<vector<int>> G;
vector<int> Jump, SubSize, Depth, Parent;
bool processed;
LCASolver(size_t n) :
G(n), Jump(n), SubSize(n), Depth(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;
G.clear(); G.shrink_to_fit();
SubSize.clear(); SubSize.shrink_to_fit();
}
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];
}
void DFSJump(int node, int jump) {
Jump[node] = jump;
int heavy = *max_element(G[node].begin(), G[node].end(), [this](int a, int b) {
return SubSize[a] < SubSize[b];
});
for (auto vec : G[node])
DFSJump(vec, vec == heavy ? 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, p;
cin >> n >> m;
LCASolver lca(n);
for (int i = 1; i < n; ++i) {
cin >> p;
lca.AddEdge(p - 1, i);
}
lca.Preprocess();
while (m--) {
int a, b;
cin >> a >> b;
cout << 1 + lca.GetLCA(a - 1, b - 1) << '\n';
}
return 0;
}