Pagini recente » Cod sursa (job #1275692) | Cod sursa (job #1728336) | Cod sursa (job #1227147) | Cod sursa (job #658439) | Cod sursa (job #3341533)
#include <bits/stdc++.h>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector<int> euler;
vector<int> first_occurrence;
vector<pair<int, int>> st[20]; // sparse table by Euler tour
vector<vector<int>> adj;
vector<int> depth;
int N;
void dfs(int node, int d) {
depth[node] = d;
first_occurrence[node] = euler.size();
euler.push_back(node);
for (auto it : adj[node]) {
dfs(it, d + 1);
euler.push_back(node); // add node again after child
}
}
void build_rmq() {
int L = euler.size();
for (int i = 0; i < 20; i++)
st[i].resize(L);
for (int i = 0; i < L; i++)
st[0][i] = {depth[euler[i]], euler[i]};
for (int k = 1; (1 << k) <= L; k++) {
for (int i = 0; i + (1 << k) <= L; i++) {
if (st[k - 1][i].first < st[k - 1][i + (1 << (k - 1))].first)
st[k][i] = st[k - 1][i];
else
st[k][i] = st[k - 1][i + (1 << (k - 1))];
}
}
}
int query(int L, int R) {
if (L > R)
swap(L, R);
int len = floor(log2(R - L + 1));
if (st[len][L].first < st[len][R - (1 << len) + 1].first)
return st[len][L].second;
else
return st[len][R - (1 << len) + 1].second;
}
int lca(int u, int v) {
return query(first_occurrence[u], first_occurrence[v]);
}
int main() {
int M, root, Q;
fin >> N >> Q;
adj.resize(N + 1);
first_occurrence.resize(N + 1);
depth.resize(N + 1);
root = 1;
for (int i = 2; i <= N; i++) {
int x;
fin >> x;
adj[x].push_back(i);
}
dfs(root, 1);
build_rmq();
for (int i = 0; i < Q; i++) {
int L, R;
fin >> L >> R;
fout << lca(L, R) << '\n';
}
return 0;
}