Pagini recente » Articole | Monitorul de evaluare | Diferente pentru aplicatii-ale-cautarii-binare intre reviziile 15 si 12 | Monitorul de evaluare | Cod sursa (job #1838863)
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <climits>
using namespace std;
int A[100010];
int E[10000000];
int H[10000000];
vector<int> Ch[100010];
int pos[100010];
int n, m;
int pos_euler;
int B[100005];
int N;
int lung_bloc, nr_bloc;
void calcMin(){
int j = 0;
int minim = 0;
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;
while((st % lung_bloc)!=0 && (st <= dr)){
if(H[st] < minim){
minim = H[st];
minim_pos = st;
}
st++;
}
while(((dr+1)%lung_bloc!=0) && (dr > st)){
if(H[dr] < minim){
minim = H[dr];
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++){
if(H[B[i]] < minim){
minim = H[B[i]];
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();
}
}
void afisEuler(){
for(int i=0; i<pos_euler; i++)
cout << E[i] << " ";
cout << endl;
cout << "H:" << endl;
for(int i=0; i<pos_euler; i++)
cout << H[i] << " ";
cout << endl;
}
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++)
{
cin >> 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;
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;
}