Pagini recente » Cod sursa (job #540686) | Cod sursa (job #2699838) | Cod sursa (job #3135530) | Cod sursa (job #3203573) | Cod sursa (job #2763198)
#include <bits/stdc++.h>
#define zeros(x) x & (-x)
using namespace std;
const int MAXN = 1e5 + 65;
const int INF = 1e8;
ifstream fin("lca.in");
ofstream fout("lca.out");
vector <int > g[MAXN];
int euler[2 * MAXN], lvl[MAXN], first[MAXN];
int rmq[30][2 * MAXN], p;
///rmq[power(dif)][first[x]] = min(lvl[eulerp[
void dfs(int node, int papa){
euler[++p] = node;
first[node] = p ;
lvl[node] = lvl[papa] + 1;
for(auto x : g[node]){
if(x != papa){
dfs(x, node);
euler[++p] = node;
}
}
}
int main(){
int n , m ; fin >> n >> m;
for(int i = 2; i <= n; ++i){
int x; fin >> x;
g[x].push_back(i);
}
dfs(1, 0);
/// rmq - nodul cu lvl minim in euler
for(int i = 1; i <= p; ++i){
rmq[0][i] = euler[i];
}
for(int i = 1; i <= 30; ++i){
for(int j = 1; j <= p; ++j){
if(j + (1 << ( i - 1 )) <= p){
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))];
}
}
}
for(int i = 1; i <= m; ++i){
int x, y; fin >> x >> y;
x = first[x];
y = first[y];
if(y < x) swap(x, y);
int dif = y - x + 1, power = 0;
for(int j = 30; j >= 0 ; --j){
if((1 << j) & dif){
power = j;
break;
}
}
int ans = 0;
if(lvl[rmq[power][x]] <= lvl[rmq[power][y - (1 << power) + 1]])
ans = rmq[power][x];
else ans = rmq[power][y - (1 << power) + 1];
fout << ans << '\n';
}
return 0;
}