Pagini recente » Cod sursa (job #2036320) | Cod sursa (job #1049037) | Cod sursa (job #283890) | Cod sursa (job #2480731) | Cod sursa (job #1221063)
#include <iostream>
#include <cstdio>
#include <cmath>
#include <vector>
#include <algorithm>
using namespace std;
#define MAX 100010
vector<int> Gr[MAX];
int N, M;
struct Node{
int X, H;
Node(){
X = 0, H = 0;
}
Node(int X, int H){
this->X = X, this->H = H;
}
};
vector<Node> Euler(1);
int First[MAX], LCA[3 * MAX][19];
void DFS(int X, int H) {
Euler.push_back(Node(X, H));
for (int i = 0; i < Gr[X].size(); i++) {
DFS(Gr[X][i], H + 1);
Euler.push_back(Node(X, H));
}
}
int main() {
int X, Y, K, L, R;
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d %d", &N, &M);
for (int i = 2; i <= N; i++) {
scanf("%d", &X);
Gr[X].push_back(i);
}
DFS(1, 0);
for (int i = 1; i < Euler.size(); i++) {
if (!First[Euler[i].X]) {
First[Euler[i].X] = i;
}
}
for (int i = 1; i < Euler.size(); i++) {
LCA[i][0] = i;
}
for (int j = 1; (1 << j) < Euler.size(); j++) {
for (int i = 1; i + (1 << j) - 1 < Euler.size(); i++) {
X = LCA[i][j-1];
Y = LCA[i + (1 << (j-1))][j-1];
if (Euler[X].H < Euler[Y].H) {
LCA[i][j] = X;
} else {
LCA[i][j] = Y;
}
}
}
for (int i = 1; i <= M; i++) {
scanf("%d %d", &X, &Y);
X = First[X];
Y = First[Y];
if (X > Y) swap(X, Y);
K = (int)(log(Y - X + 1) / log(2));
L = LCA[X][K];
R = LCA[Y - (1 << K) + 1][K];
if (Euler[L].H < Euler[R].H) {
printf("%d\n", Euler[L].X);
} else {
printf("%d\n", Euler[R].X);
}
}
return 0;
}