Pagini recente » Cod sursa (job #1111770) | Cod sursa (job #653250) | Istoria paginii runda/agm2/clasament | Cod sursa (job #1105841) | Cod sursa (job #1839119)
#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[100010];
int n, m;
int pos_euler;
int B[100005];
int N;
int lung_bloc, nr_bloc;
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 query_secv(int a, int b){
int minim = H[a];
int minim_pos = a;
for(int i=a; i<=b;i++){
if(H[i] < minim){
minim = H[i];
minim_pos = i;
}
}
return minim_pos;
}
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_secv(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;
}