Pagini recente » Cod sursa (job #2337326) | Cod sursa (job #978242) | Cod sursa (job #3272217) | Cod sursa (job #1981227) | Cod sursa (job #2759556)
/*
Sursa experimentala
*/
#include <iostream>
#include <fstream>
#include <vector>
#define NMAX 100000 //o suta de mii
#define LOGMAX2 17
using namespace std;
ifstream fin ("lca.in");
ofstream fout ("lca.out");
struct element{
int nod;
int height;
};
int dimE;
int first[NMAX + 1];
element O[2 * NMAX][LOGMAX2 + 1];
element e[2 * NMAX];
vector <int> v[NMAX + 1];
void DFS(int nod, int height){
dimE++;
e[dimE].nod = nod;
e[dimE].height = height;
first[nod] = dimE;
for(int i = 0; i < v[nod].size(); i++){
int X = v[nod][i];
DFS(X, height + 1);
dimE++;
e[dimE].nod = nod;
e[dimE].height = height;
}
}
inline void buildEuler(){
DFS(1, 1); //stiu ca e radacina
}
element rezultant(element A, element B){
if(A.height <= B.height){
return A;
}
else {
return B;
}
}
inline void buildVector(){
for(int i = dimE; i >= 1; i--){
O[i][0] = e[i];
}
for(int i = dimE; i >= 1; i--){
for(int j = 1; i + (1 << j) - 1 <= dimE; j++){
O[i][j] = rezultant(O[i][j - 1], O[i + (1 << (j - 1)) ][j - 1]);
}
}
}
int putereDoiLowerbound(int x){
int lo = -1;
int hi = LOGMAX2 + 1;
while(hi - lo > 1){
int mid = lo + (hi - lo) / 2;
if( (1 << mid) <= x ){
lo = mid;
}
else {
hi = mid;
}
}
return lo;
}
int main()
{
int N, M;
fin >> N >> M;
for(int i = 2; i <= N; i++){
int x;
fin >> x;
v[ x ].push_back(i);
}
buildEuler();
buildVector();
for(int q = 1; q <= M; q++){
//printf("q = %d\n", q);
int a, b;
fin >> a >> b;
int A = first[a];
int B = first[b];
if(A > B){
swap(A, B);
}
int k = putereDoiLowerbound(B - A + 1);
fout << rezultant(O[A][k], O[B - (1 << k) + 1][k]).nod << "\n";
//printf("\n");
}
return 0;
}