Pagini recente » Cod sursa (job #450806) | Cod sursa (job #2657394) | Cod sursa (job #406841) | Cod sursa (job #2132294) | Cod sursa (job #2093489)
#include <fstream>
#include <vector>
#include <cmath>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
const int INF = 1e9;
void Dfs(int cur_node, int cur_level, int &index, vector < int > &euler,
vector < vector < int > > &gr, vector < int > &first_ap, vector < int > &level) {
level[cur_node] = cur_level;
euler[++ index] = cur_node;
if (not first_ap[cur_node]) {
first_ap[cur_node] = index;
}
for (auto x : gr[cur_node]) {
Dfs(x, cur_level + 1, index, euler, gr, first_ap, level);
euler[++ index] = cur_node;
}
}
int main() {
int n, m;
cin >> n >> m;
vector < int > tata(n + 1);
vector < vector < int > > gr(n + 1);
for (int i = 2; i <= n; i ++) {
cin >> tata[i];
gr[tata[i]].push_back(i);
}
int index = 0;
vector < int > level(n + 1);
vector < int > first_ap(n + 1);
vector < int > euler(1e6 + 7);
Dfs(1, 1, index, euler, gr, first_ap, level);
vector < int > log_2(1e6 + 7);
log_2[1] = 0;
for (int i = 2; i < (int) log_2.size(); i ++) {
log_2[i] = log_2[i / 2] + 1;
}
int lim = log_2[index + 1];
vector < vector < int > > dp(lim + 1, vector < int > (index + 1));
for (int i = 1; i <= index; i ++) {
dp[0][i] = euler[i];
}
for (int i = 1; i <= lim; i ++) {
for (int j = 1; j <= index; j ++) {
int l = dp[i - 1][j];
int k = j + (1 << (i - 1));
if (k <= index) {
int r = dp[i - 1][k];
if (level[r] < level[l]) {
l = r;
}
}
dp[i][j] = l;
}
}
int x, y;
for (int i = 1; i <= m; i ++) {
cin >> x >> y;
x = first_ap[x];
y = first_ap[y];
if (x > y) {
swap(x, y);
}
int k = log_2[y - x + 1];
int l = dp[k][x];
int r = dp[k][y - (1 << k) + 1];
if (level[l] <= level[r]) {
cout << l << '\n';
}
else {
cout << r << '\n';
}
}
}