Pagini recente » Cod sursa (job #2264967) | Cod sursa (job #2103058) | Cod sursa (job #883268) | Cod sursa (job #755678) | Cod sursa (job #3156520)
#include <fstream>
#include <vector>
#include <climits>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
vector<vector<int>> children;
vector<int> l, pos, logg, level;
int min_level(int a, int b){
return (level[l[a]] < level[l[b]] ? a : b);
}
void dfs(int nod, int L){
l.push_back(nod);
pos[nod] = l.size() - 1;
level[nod] = L;
for(int child:children[nod]){
dfs(child, L+1);
l.push_back(nod);
}
}
vector<vector<int>> RMQ(){
const int n = l.size();
vector<vector<int>> dp(20, vector<int>(n));
for(int i=0; i<n; i++)
dp[0][i] = i;
for(int j=1; (1<<j) <= n; j++){
for(int i = n - 1; i >= 0; i--){
if(i + (1<<(j)) - 1 >= n)
continue;
dp[j][i] = min_level(dp[j-1][i], dp[j-1][i + (1<<(j-1))]);
}
}
return dp;
}
int main(){
int n, q;
cin>>n>>q;
pos.resize(n+1, INT_MAX);
level.resize(n+1);
children.resize(n+1);
for(int i=2; i<=n; i++){
int x;
cin>>x;
children[x].push_back(i);
}
dfs(1, 0);
logg.resize(l.size()+1);
logg[0] = logg[1] = 0;
for(int i=2; i<=l.size(); i++)
logg[i] = logg[i/2] + 1;
vector<vector<int>> dp = RMQ();
while(q--){
int x, y;
cin>>x>>y;
if(pos[x] < pos[y])
swap(x, y);
int size = pos[x] - pos[y] + 1;
const int sol = min_level(dp[logg[size]][pos[y]], dp[logg[size]][pos[x] - (1<<logg[size]) + 1]);
cout<<l[sol]<<'\n';
}
return 0;
}