Pagini recente » Cod sursa (job #80462) | Cod sursa (job #2294094) | Cod sursa (job #537153) | Cod sursa (job #919193) | Cod sursa (job #3003728)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int DIM = 100010;
const int LOG = 21;
struct rmqItem {
int node, level;
} rmq[LOG][2 * DIM];
int n, m, x, y;
int currPos = 0;
int father[DIM], start[DIM], exp[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 calcRMQ() {
for (int p = 1; p < LOG; p++) {
for (int i = 1; i <= currPos; i++) {
rmqItem left = rmq[p - 1][i];
if (i + (1 << (p - 1)) <= currPos) {
rmqItem right = rmq[p - 1][i + (1 << (p - 1))];
rmq[p][i] = (left.level < right.level ? left : right);
} else {
rmq[p][i] = left;
}
}
}
}
void calcMaxExp() {
exp[1] = 0;
for (int i = 2; i <= currPos; i++)
exp[i] = 1 + exp[i / 2];
}
int getLCA(int node1, int node2) {
int pos1 = start[node1];
int pos2 = start[node2];
if (pos1 > pos2) swap(pos1, pos2);
int currExp = exp[pos2 - pos1 + 1];
int pow = (1 << currExp);
rmqItem left = rmq[currExp][pos1];
rmqItem right = rmq[currExp][pos2 - pow + 1];
return (left.level < right.level ? 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);
}
dfs(1, 0);
calcRMQ();
calcMaxExp();
for (int i = 1; i <= m; i++) {
fin >> x >> y;
fout << getLCA(x, y) << '\n';
}
return 0;
}