Pagini recente » Cod sursa (job #843131) | Cod sursa (job #3198692) | Cod sursa (job #1785766) | Cod sursa (job #1324162) | Cod sursa (job #2973348)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int DIM = 100010;
const int MAX_LOG = 20;
int n, m, node1, node2;
int father[DIM], ancestors[MAX_LOG][DIM], level[DIM];
int first[DIM], last[DIM], currPos;
vector<int> l[DIM];
void dfs(int node, int lvl) {
level[node] = lvl;
first[node] = ++currPos;
for (auto adjNode : l[node])
dfs(adjNode, lvl + 1);
last[node] = ++currPos;
}
void calculateAncestors() {
for (int node = 1; node <= n; node++)
ancestors[0][node] = father[node];
for (int exp = 1; exp < MAX_LOG; exp++)
for (int node = 1; node <= n; node++)
ancestors[exp][node] = ancestors[exp - 1][ancestors[exp - 1][node]];
}
inline bool isAncestor(int node1, int node2) {
return first[node1] <= first[node2] && last[node2] <= last[node1];
}
inline int getLCA(int node1, int node2) {
if (isAncestor(node1, node2))
return node1;
if (isAncestor(node2, node1))
return node2;
for (int pow = MAX_LOG - 1; pow >= 0; pow--) {
int ancestor = ancestors[pow][node1];
if (ancestor != 0 && !isAncestor(ancestor, node2))
node1 = ancestor;
}
return ancestors[0][node1];
}
int main() {
fin >> n >> m;
for (int i = 2; i <= n; i++) {
fin >> father[i];
l[father[i]].push_back(i);
}
currPos = 0;
dfs(1, 0);
calculateAncestors();
for (int i = 1; i <= m; i++) {
fin >> node1 >> node2;
fout << getLCA(node1, node2) << '\n';
}
return 0;
}