Pagini recente » Cod sursa (job #2634860) | Cod sursa (job #1804516)
#include <iostream>
#include <vector>
#include <math.h>
#include <stdio.h>
#include <utility>
#include <stdlib.h>
using namespace std;
#define max_n 100005
vector<int> first(max_n), euler_nodes, euler_levels;
vector<vector<int> > child(max_n), rmq;
int n, m, a;
void make_euler(int node, int level) {
euler_nodes.push_back(node);
euler_levels.push_back(level);
first[node] = euler_nodes.size() - 1;
for (int i = 0; i < child[node].size(); i ++) {
make_euler(child[node][i], level + 1);
euler_nodes.push_back(node);
euler_levels.push_back(level);
}
}
void make_rmq() {
int s = euler_levels.size();
int l = (int)(log(s) / log(2));
vector<int> t(l + 1);
for (int i = 0; i < s; i ++)
rmq.push_back(t);
for (int i = 0; i < s; i ++)
rmq[i][0] = i;
for (int j = 1; j <= l; j ++)
for (int i = 0; i < s - (1 << (j - 1)); i ++)
rmq[i][j] = (euler_levels[rmq[i][j - 1]] < euler_levels[rmq[i + (1 << (j - 1))][j - 1]] ? rmq[i][j - 1] : rmq[i + (1 << (j - 1))][j - 1]);
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d %d", &n, &m);
for (int i = 0; i < n - 1; i ++) {
scanf("%d", &a);
child[a].push_back(i + 2);
}
make_euler(1, 0);
/*for (int i = 0; i < euler_nodes.size(); i ++)
cout << euler_nodes[i] << " ";
cout << endl;
for (int i = 0; i < euler_levels.size(); i ++)
cout << euler_levels[i] << " ";
cout << endl << endl;*/
make_rmq();
/*for (int i = 0; i < rmq.size(); i ++) {
for (int j = 0; j < rmq[0].size(); j ++)
cout << rmq[i][j] << " ";
cout << endl;
} */
for (int i = 0; i < m; i ++) {
int n1, n2;
scanf("%d %d", &n1, &n2);
int r1 = first[n1], r2 = first[n2];
int range = abs(r2 - r1) + 1, lr = (int)(log(range) / log(2));
//cout << lr << endl;
int sol = rmq[min(r1, r2)][lr];
//cout << sol << endl;
range -= (1 << lr);
if (range != 0)
sol = (euler_levels[sol] < euler_levels[rmq[min(r1, r2) + range][lr]] ? sol : rmq[min(r1, r2) + range][lr]);
printf("%d\n", euler_nodes[sol]);
}
return 0;
}