Pagini recente » Cod sursa (job #1181071) | Cod sursa (job #995875) | Cod sursa (job #2236742) | Cod sursa (job #1704175) | Cod sursa (job #2984938)
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
constexpr int LIM = 100005;
constexpr int LG = 25;
int N, M, node, cnt, first[LIM], lg2[2 * LIM];
pair<int, int> RMQ[LG][2 * LIM];
vector<int> G[LIM];
static void dfs(int node, int level) {
RMQ[0][++cnt] = { node, level };
first[node] = cnt;
for (const int adj : G[node]) {
dfs(adj, level + 1);
RMQ[0][++cnt] = { node, level };
}
}
static inline void prepare_LCA() {
dfs(1, 1);
for (int i = 1; i < LG; ++i)
for (int j = 1; j <= cnt; ++j) {
RMQ[i][j] = RMQ[i - 1][j];
if (j + (1 << (i - 1)) <= cnt) {
if (RMQ[i][j].second > RMQ[i - 1][j + (1 << (i - 1))].second)
RMQ[i][j] = RMQ[i - 1][j + (1 << (i - 1))];
}
}
lg2[1] = 0;
for (int i = 2; i <= cnt; ++i)
lg2[i] = lg2[i / 2] + 1;
}
static inline int LCA(int node1, int node2) {
int l = first[node1], r = first[node2];
if (l > r) swap(l, r);
const int len = r - l + 1;
int lg_len = lg2[len];
pair<int, int> RMQ1 = RMQ[lg_len][l];
pair<int, int> RMQ2 = RMQ[lg_len][r - (1 << lg_len) + 1];
if (RMQ1.second < RMQ2.second)
return RMQ1.first;
return RMQ2.first;
}
int main() {
fin >> N >> M;
for (int i = 2; i <= N; ++i) {
fin >> node;
G[node].push_back(i);
}
prepare_LCA();
int node1, node2;
for (; M; --M) {
fin >> node1 >> node2;
fout << LCA(node1, node2) << '\n';
}
fin.close();
fout.close();
return 0;
}