Pagini recente » Cod sursa (job #2118868) | Cod sursa (job #184002) | Cod sursa (job #370279) | Cod sursa (job #6092) | Cod sursa (job #1162933)
#include <cstdio>
#include <vector>
using namespace std;
#define FILEIN "lca.in"
#define FILEOUT "lca.out"
#define NMAX 100005
#define LGMAX 22
int LG [NMAX << 1],
EulerTour[NMAX << 1],
EulerLvl [NMAX << 1],
First [NMAX << 1],
RMQ[NMAX << 2][LGMAX],
N, M, Pos = 0;
vector<int> A[NMAX];
void EulerTraversal(int x, int depth) {
EulerTour[++Pos] = x;
EulerLvl [Pos] = depth;
First [x] = Pos;
for ( vector<int>::iterator it = A[x].begin(); it != A[x].end(); ++it ) {
EulerTraversal(*it, depth + 1);
EulerTour[++Pos] = x;
EulerLvl [Pos] = depth;
}
}
void BuildRMQ() {
LG[1] = 0;
for ( int i = 2; i <= Pos; i++ )
LG[i] = LG[i/2] + 1;
for ( int i = 1; i <= Pos; i++ ) {
RMQ[i][0] = i;
}
for ( int j = 1; (1 << j) <= Pos; j++ ) {
for ( int i = 1; i + (1 << (j-1)) <= Pos; i++ ) {
RMQ[i][j] = RMQ[i][j-1];
if (EulerLvl[RMQ[i + (1 << (j-1))][j-1]] < EulerLvl[RMQ[i][j]]) {
RMQ[i][j] = RMQ[i + (1 << (j-1))][j-1];
}
}
}
}
inline int LCA(int x, int y) {
int xPos = First[x],
yPos = First[y];
if (xPos > yPos) {
int tmp = xPos;
xPos = yPos;
yPos = tmp;
}
int L = LG[yPos - xPos + 1];
int sol = RMQ[xPos][L];
if (EulerLvl[RMQ[yPos - (1 << L) + 1][L]] < EulerLvl[RMQ[xPos][L]]) {
sol = RMQ[yPos - (1 << L) + 1][L];
}
return EulerTour[sol];
}
int main() {
freopen(FILEIN, "r", stdin);
freopen(FILEOUT, "w", stdout);
scanf("%d %d", &N, &M);
for ( int i = 1, x; i < N; i++ ) {
scanf("%d", &x);
A[x].push_back(i+1);
}
EulerTraversal(1, 0);
BuildRMQ();
for ( int x, y; M; M-- ) {
scanf("%d %d", &x, &y);
printf("%d\n", LCA(x, y));
}
return 0;
}