Pagini recente » Cod sursa (job #2793416) | Cod sursa (job #3309228) | Cod sursa (job #3309895) | Monitorul de evaluare | Cod sursa (job #3358163)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int nMax = 1e5 + 1;
const int logMax = 18;
vector<int> List[nMax];
vector<int> eulerTour, height, firstPos(nMax);
void buildEulerTour(int node, int h) {
eulerTour.push_back(node);
height.push_back(h);
firstPos[node] = eulerTour.size() - 1;
for (const int& child : List[node]) {
buildEulerTour(child, h + 1);
eulerTour.push_back(node);
height.push_back(h);
}
}
int table[2 * nMax - 1][logMax];
void buildSparseTable(int n) {
for (int i = 0; i < n; i++) {
table[i][0] = i;
}
for (int j = 1; (1 << j) <= n; j++) {
for (int i = 0; i + (1 << j) <= n; i++) {
if (height[table[i][j - 1]] < height[table[i + (1 << (j - 1))][j - 1]]) {
table[i][j] = table[i][j - 1];
}
else {
table[i][j] = table[i + (1 << (j - 1))][j - 1];
}
}
}
}
int query(int left, int right) {
int p = log2(right - left + 1);
if (height[table[left][p]] < height[table[right - (1 << p) + 1][p]]) {
return eulerTour[table[left][p]];
}
return eulerTour[table[right - (1 << p) + 1][p]];
}
int lca(int node1, int node2) {
int pos1 = firstPos[node1];
int pos2 = firstPos[node2];
if (pos1 > pos2) {
swap(pos1, pos2);
}
return query(pos1, pos2);
}
int main() {
ios::sync_with_stdio(false);
int n, m;
fin >> n >> m;
for (int i = 2; i <= n; i++) {
int x;
fin >> x;
List[x].push_back(i);
}
buildEulerTour(1, 0);
buildSparseTable(2 * n - 1);
for (int i = 0; i < m; i++) {
int node1, node2;
fin >> node1 >> node2;
fout << lca(node1, node2) << "\n";
}
return 0;
}