Pagini recente » Cod sursa (job #1416651) | Borderou de evaluare (job #2510114) | Cod sursa (job #2339551) | Cod sursa (job #669775) | Cod sursa (job #2982459)
#include <bits/stdc++.h>
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
const int kN = 2e5 + 5;
vector<int>g[kN];
int n, q;
int euler[kN], first[kN], level[kN], len;
int rmq[kN][20], lg[kN];
void dfs (int nod, int dad = -1, int h = 1){
euler[++len] = nod;
level[len] = h;
first[nod] = len;
for (int u : g[nod]){
if (u == dad){
continue;
}
dfs(u, nod, h + 1);
euler[++len] = nod;
level[len] = h;
}
}
void precalc (){
for (int i = 2; i < kN; i++){
lg[i] = 1 + lg[i / 2];
}
for (int i = 1; i <= len; i++){
rmq[i][0] = i;
}
for (int j = 1; j < 20; j++){
for (int i = 1; i + (1 << j) <= len; i++){
rmq[i][j] = rmq[i][j - 1];
if (level[rmq[i][j]] > level[rmq[i + (1 << (j - 1))][j - 1]]){
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
}
}
}
int lca (int x, int y){
x = first[x], y = first[y];
if (x > y){
swap(x, y);
}
int k = lg[y - x + 1];
int ans = rmq[x][k];
if (level[ans] > level[rmq[y - (1 << k) + 1][k]]){
ans = rmq[y - (1 << k) + 1][k];
}
return euler[ans];
}
int main(){
ios_base::sync_with_stdio(false);
fin >> n >> q;
for (int i = 2; i <= n; i++){
int x; fin >> x;
g[x].push_back(i);
}
dfs(1);
precalc();
while (q--){
int x, y; fin >> x >> y;
fout << lca(x, y) << '\n';
}
}