Pagini recente » Cod sursa (job #1731649) | Cod sursa (job #2425366) | Monitorul de evaluare | Diferente pentru warm-up-2019/solutii/shoturi intre reviziile 59 si 99 | Cod sursa (job #403005)
Cod sursa(job #403005)
#include <cstdio>
#include <vector>
using namespace std;
#define Nmax 100010
int n, T, N, niv, k;
int E[Nmax << 1], Niv[Nmax << 1], poz[Nmax << 1], lg[Nmax << 1], rmq[18][Nmax << 1];
vector <int> V[Nmax];
void euler (int nod) {
E[++N] = nod; Niv[N] = niv; poz[nod] = N;
for (int i = 0; i < (int)V[nod].size (); i++) {
niv++;
euler (V[nod][i]);
niv--; E[++N] = nod; Niv[N] = niv;
}
}
void Rmq () {
int i, l1, l2; rmq[0][1] = 1;
for (i = 2; i <= N; i++)
rmq[0][i] = i, lg[i] = lg[i >> 1] + 1;
for (k = 1; (1 << k) <= N; k++) {
l1 = (1 << k); l2 = (1 << (k - 1));
for (i = 1; i + l1 - 1 <= N; i++)
if ( Niv[ rmq[k-1][i + l2] ] < Niv[ rmq[k-1][i] ] )
rmq[k][i] = rmq[k-1][i + l2];
else
rmq[k][i] = rmq[k-1][i];
}
}
int main () {
freopen ("lca.in", "r", stdin);
freopen ("lca.out", "w", stdout);
scanf ("%d %d", &n, &T);
int x;
for (int i = 2; i <= n; i++)
scanf ("%d", &x), V[x].push_back (i);
niv++; euler (1);
Rmq ();
int a, b, y, k;
for (; T; T--) {
scanf ("%d %d", &x, &y);
if (poz[x] < poz[y])
a = poz[x], b = poz[y];
else
a = poz[y], b = poz[x];
k = lg[b - a + 1];
a = rmq[k][a]; b = rmq[k][b - (1 << k) + 1] ;
if (Niv[a] < Niv[b])
printf ("%d\n", E[a]);
else
printf ("%d\n", E[b]);
}
return 0;
}