Pagini recente » Cod sursa (job #2045888) | Istoria paginii utilizator/brillante | Cod sursa (job #608465) | Cod sursa (job #1130530) | Cod sursa (job #3205983)
#include <fstream>
#include <iostream>
#include <vector>
#define NMAX 100'007
#define LOG 20
std::ofstream cout("lca.out");
std::ifstream cin("lca.in");
int n, m;
std::vector<int> G[NMAX];
int up[NMAX][40], tin[NMAX], tout[NMAX], timp = 0;
void citire() {
cin >> n >> m;
int a;
for (int i = 1; i < n; i++) {
cin >> a;
G[a].push_back(i + 1);
}
}
void dfs(int nod, int tata) {
tin[nod] = ++timp;
up[nod][0] = tata;
for (int j = 1; j <= LOG; j++) {
up[nod][j] = up[up[nod][j - 1]][j - 1];
}
for (auto it : G[nod]) {
if (it != tata)
dfs(it, nod);
}
tout[nod] = ++timp;
}
bool is_anc(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; }
int lca(int a, int b) {
if (is_anc(a, b))
return a;
if (is_anc(b, a))
return b;
for (int i = LOG; i >= 0; i--) {
if (!is_anc(up[a][i], b))
a = up[a][i];
}
return up[a][0];
}
int main() {
citire();
dfs(1, 1);
int u, v;
for (int i = 1; i <= m; i++) {
cin >> u >> v;
cout << lca(u, v) << '\n';
}
return 0;
}