Pagini recente » Cod sursa (job #436504) | Cod sursa (job #504307) | Cod sursa (job #1426415) | Cod sursa (job #79268) | Cod sursa (job #1839509)
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <climits>
using namespace std;
int A[100010];
int E[100000000];
int H[100000000];
vector<int> Ch[100010];
int pos[100000000];
int n, m;
int pos_euler;
int B[100000000];
int N;
int lung_bloc, nr_bloc;
void calcMin(){
int j = 0;
int minim = INT_MAX;
int minim_pos = 0;
for(int i=0; i<nr_bloc; i++){
minim = H[j];
minim_pos = j;
for(int k=0; k<lung_bloc; k++){
if(H[j] < minim){
minim = H[j];
minim_pos = j;
}
j++;
}
B[i] = minim_pos;
}
}
int query(int st, int dr){
int minim = H[st];
int minim_pos = st;
int k = 0;
while((st % lung_bloc)!=0 && (st <= dr)){
k = H[st];
if(k < minim){
minim = k;
minim_pos = st;
}
st++;
}
while(((dr+1)%lung_bloc!=0) && (dr >= st)){
k = H[dr];
if(k < minim){
minim = k;
minim_pos = dr;
}
dr--;
}
int st_bloc = st/lung_bloc;
int dr_bloc = dr/lung_bloc;
if((st % lung_bloc==0) && (dr - st+1) >= lung_bloc )
for(int i=st_bloc; i<=dr_bloc; i++){
k = H[B[i]];
if( k < minim){
minim = k;
minim_pos = B[i];
}
}
return minim_pos;
}
void parcurgere_euleriana(int nod, int h){
queue<int> Q;
Q.push(nod);
E[pos_euler] = nod;
H[pos_euler] = h;
pos[nod] = pos_euler;
pos_euler++;
while(!Q.empty()){
int nod = Q.front();
for(vector<int>::iterator it = Ch[nod].begin(); it!=Ch[nod].end(); it++){
parcurgere_euleriana(*it, h+1);
E[pos_euler] = nod;
H[pos_euler] = h;
pos_euler++;
}
Q.pop();
}
}
int minimEuler(int a, int b){
int pos_a = pos[a];
int pos_b = pos[b];
if(pos_a > pos_b)
swap(pos_a, pos_b);
int minim_pos = query(pos_a, pos_b);
return minim_pos;
}
int main()
{
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d %d", &n, &m);
for(int i=1; i<n; i++)
{
scanf("%d", &A[i]);
Ch[A[i]].push_back(i+1);
}
parcurgere_euleriana(1, 0);
//afisEuler();
N = pos_euler;
lung_bloc = sqrt(N);
nr_bloc = N/lung_bloc;
int N2 =lung_bloc*nr_bloc;
if( N2 < N){
for(int i=N; i<N2+lung_bloc; i++)
H[i] = H[N-1];
nr_bloc++;
N = N2+lung_bloc;
pos_euler = N;
}
calcMin();
int a, b;
for(int i=0; i<m; i++){
scanf("%d %d", &a, &b);
printf("%d\n", E[minimEuler(a, b)] );
}
return 0;
}