Pagini recente » Cod sursa (job #2270457) | Cod sursa (job #2511443) | Cod sursa (job #1140172) | Cod sursa (job #638490) | Cod sursa (job #2974277)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
struct rmqItem {
int node, lvl;
};
const int DIM = 100010;
const int MAX_LOG = 21;
int n, m, x, y, currPos;
int father[DIM], start[DIM], maxPow[2 * DIM];
rmqItem rmq[MAX_LOG][2 * DIM];
vector<int> l[DIM];
void dfs(int node, int lvl) {
rmq[0][++currPos] = { node, lvl };
start[node] = currPos;
for (auto son : l[node]) {
dfs(son, lvl + 1);
rmq[0][++currPos] = { node, lvl };
}
}
void calculateRMQ() {
for (int pow = 1; pow < MAX_LOG; pow++) {
for (int i = 1; i <= currPos; i++) {
rmqItem left = rmq[pow - 1][i];
if (i + (1 << (pow - 1)) <= currPos) {
rmqItem right = rmq[pow - 1][i + (1 << (pow - 1))];
rmq[pow][i] = left.lvl < right.lvl ? left : right;
} else {
rmq[pow][i] = left;
}
}
}
}
void calculateMaxPow() {
maxPow[1] = 0;
for (int i = 2; i <= currPos; i++)
maxPow[i] = maxPow[i / 2] + 1;
}
int getLCA(int node1, int node2) {
int pos1 = start[node1];
int pos2 = start[node2];
if (pos1 > pos2)
swap(pos1, pos2);
int pow = maxPow[pos2 - pos1 + 1];
rmqItem left = rmq[pow][pos1];
rmqItem right = rmq[pow][pos2 - (1 << pow) + 1];
return (left.lvl < right.lvl ? left.node : right.node);
}
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);
calculateRMQ();
calculateMaxPow();
for (int i = 1; i <= m; i++) {
fin >> x >> y;
fout << getLCA(x, y) << '\n';
}
return 0;
}