Pagini recente » Profil maritim | Cod sursa (job #2247198) | Statistici Tiberiu Amarie (Tiberiw) | Istoria paginii fmi-no-stress-3/clasament | Cod sursa (job #2162221)
#include <cstdio>
#include <cmath>
#include <vector>
using namespace std;
int n, m;
vector<int> vecini[100005];
int firstApp[100005];
int nr = 1;
int lca[200005];
int rmq[200005][22];
void citire(){
scanf("%d %d", &n, &m);
int x;
for(int i = 2; i <= n; i++){
scanf("%d", &x);
vecini[x].push_back(i);
}
}
void addInLca(int x, int d){
rmq[nr][0] = x;
if(firstApp[x] == 0){
firstApp[x] = nr;
}
if(lca[x] == 0){
lca[x] = d;
}
nr++;
}
void dfs(int x, int d){
addInLca(x, d);
int l = vecini[x].size();
for(int i = 0; i < l; i++){
dfs(vecini[x][i], d + 1);
addInLca(x, d);
}
}
void createRmq(){
for(int i = 1; (1 << i) <= nr; i++){
for(int j = 1; j + (1 << (i - 1)) <= nr; j++){
if(lca[rmq[j][i - 1]] < lca[rmq[j + (1 << (i - 1))][i - 1]]){
rmq[j][i] = rmq[j][i - 1];
}
else{
rmq[j][i] = rmq[j + (1 << (i - 1))][i - 1];
}
}
}
}
int query(int x, int y){
x = firstApp[x];
y = firstApp[y];
if(x > y){
swap(x, y);
}
int l = y - x + 1;
int lg = log2(l);
if(lca[rmq[x][lg]] < lca[rmq[y - (1 << lg) + 1][lg]]){
return rmq[x][lg];
}
else{
return rmq[y - (1 << lg) + 1][lg];
}
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int x, y;
citire();
dfs(1, 1);
createRmq();
for(int i = 0; i < m; i++){
scanf("%d %d", &x, &y);
printf("%d\n", query(x, y));
}
return 0;
}