Pagini recente » Cod sursa (job #987096) | Cod sursa (job #3349677) | Cod sursa (job #342365) | Cod sursa (job #2172845) | Cod sursa (job #3306306)
// 1 2 4 7 4 8 4 2 5 2 6 9 6 2 1 3 10 3 11 3 1
// | |
// 0 1 2 3 2 3 2 1 2 1 2 3 ...
//#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, m, x, y;
vector<int> v[100005];
vector<pair<int, int>> euler; // indexat de la 0
pair<int, int> rmq[400005][20]; // {nivel, nodul}
int ap[100005], first[100005];
void dfs(int nod, int nivel) {
euler.push_back({nod, nivel});
if(ap[nod] == 0) {
ap[nod] = 1;
first[nod] = euler.size() - 1;
}
for(auto u : v[nod]) {
dfs(u, nivel + 1);
euler.push_back({nod, nivel});
}
}
int nrmq;
int lg[400001];
void precalculareRmq() {
nrmq = euler.size();
for(int i = 2; i <= nrmq; i ++) {
lg[i] = lg[i/2] + 1;
}
for(int i = 0; i < nrmq; i ++)
rmq[i][0] = {euler[i].second, euler[i].first};
for(int i = 1; (1 << i) < nrmq; i ++) {
for(int j = 0; j + (1 << i) - 1 < nrmq; j ++) {
rmq[j][i] = min(rmq[j][i-1], rmq[j + (1 << (i-1))][i-1]);
}
}
}
int queryRmq(int st, int dr) {
int lungime = dr - st + 1;
int loga = lg[lungime];
return min(rmq[st][loga], rmq[dr - (1 << loga) + 1][loga]).second;
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n-1; i ++) {
cin >> x;
// x este tatal lui i+1
v[x].push_back(i+1);
}
dfs(1, 0);
precalculareRmq();
for(int i = 1; i <= m; i ++) {
cin >> x >> y;
x = first[x];
y = first[y];
if(y < x)
swap(x, y);
cout << queryRmq(x, y) << '\n';
}
return 0;
}