Pagini recente » Cod sursa (job #3244873) | Cod sursa (job #769394) | Cod sursa (job #64085) | Cod sursa (job #2181411) | Cod sursa (job #1653215)
#include <fstream>
#include <cmath>
#include <vector>
#define INF 0x3f3f3f3f
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector <int> G[100005];
int pos[100005], n, q, rmq[20][100005], euler[200005], lvl[200005], sz;
bool used[100005];
void euler_init(int node, int level) {
used[node] = true;
++sz;
euler[sz] = node;
lvl[sz] = level;
pos[node] = sz;
for(auto it: G[node]) {
if(used[it]) {
continue;
}
euler_init(it, level + 1);
++sz;
euler[sz] = node;
lvl[sz] = level;
}
}
void rmq_init() {
for(int i = 1; i <= sz; ++i) {
rmq[0][i] = i;
}
for(int i = 1; (1 << i) <= sz; ++i) {
for(int j = 1; j + (1 << i) <= sz; ++j) {
if(lvl[rmq[i - 1][j]] <= lvl[rmq[i - 1][j + (1 << (i - 1))]]) {
rmq[i][j] = rmq[i - 1][j];
}
else {
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
}
}
int query(int lft, int rgt) {
int line, skip, rmq_ans;
skip = rgt - lft + 1;
line = log2(skip);
if(lvl[rmq[line][lft]] <= lvl[rmq[line][rgt + 1 - (1 << line)]]) {
rmq_ans = rmq[line][lft];
}
else {
rmq_ans = rmq[line][rgt + 1 - (1 << line)];
}
return euler[rmq_ans];
}
int main() {
cin >> n >> q;
for(int i = 2; i <= n; ++i) {
int x;
cin >> x;
G[x].push_back(i);
}
euler_init(1, 0);
rmq_init();
/*for(int i = 0; i <= log2(lvl.size()); ++i) {
for(int j = 1; j <= lvl.size(); ++j) {
cout << rmq[i][j] << ' ';
}
cout << '\n';
}*/
for(int i = 1; i <= q; ++i) {
int node1, node2;
cin >> node1 >> node2;
if(pos[node1] > pos[node2]) {
swap(node1, node2);
}
cout << query(pos[node1], pos[node2]) << '\n';
}
return 0;
}