Pagini recente » Cod sursa (job #2164079) | Cod sursa (job #3225925) | Cod sursa (job #2182595) | Cod sursa (job #2869514) | Cod sursa (job #1500958)
#include <cstdio>
#include <vector>
using namespace std;
const int NMAX = 100010;
const int logNMAX = 18;
int N, Q;
vector<int> g[NMAX];
int rmq[logNMAX][NMAX * 2];
int lvl[NMAX * 2], euler[NMAX * 2], prim[NMAX * 2], crt;
int log[NMAX * 2];
int DFS (int nod, int niv) {
euler[++crt] = nod;
lvl[crt] = niv;
prim[nod] = crt;
for (int i = 0; i < g[nod].size (); i++) {
DFS (g[nod][i], niv + 1);
euler[++crt] = nod;
lvl[crt] = niv;
}
}
void RMQ () {
log[0] = log[1] = 0;
log[2] = 1;
rmq[0][0] = 0;
rmq[0][1] = 1;
for (int i = 2; i <= crt; i++) {
log[i] = log[i / 2] + 1;
rmq[0][i] = i;
}
for (int i = 1; i <= log[crt]; i++) {
for (int j = 1; j + (1 << i) <= crt + 1; j++) {
if (lvl[ rmq[i - 1][j] ] < lvl[ rmq[i - 1][j + (1 << (i - 1))] ]) {
rmq[i][j] = rmq[i - 1][j];
}
else {
rmq[i][j] = rmq[i - 1][j + (1 << (i - 1))];
}
}
}
}
int LCA (int x, int y) {
if (prim[y] < prim[x]) {
int aux = y;
y = x;
x = aux;
}
int lg = log[prim[y] - prim[x] + 1];
int ans;
if (lvl[ rmq[lg][prim[x]] ] < lvl[ rmq[lg][prim[y] - (1 << lg) + 1] ]) {
ans = euler[ rmq[lg][prim[x]] ];
}
else {
ans = euler[ rmq[lg][prim[y] - (1 << lg) + 1] ];
}
return ans;
}
int main () {
freopen ("lca.in", "r", stdin);
freopen ("lca.out", "w", stdout);
scanf ("%d%d", &N, &Q);
for (int i = 2; i <= N; i++) {
int X;
scanf ("%d", &X);
g[X].push_back (i);
}
DFS (1, 0);
RMQ ();
while (Q--) {
int X, Y;
scanf ("%d%d", &X, &Y);
printf ("%d\n", LCA (X, Y));
}
return 0;
}