Pagini recente » Cod sursa (job #253743) | Istoria paginii utilizator/fan_club | Cod sursa (job #991917) | Monitorul de evaluare | Cod sursa (job #2290769)
#include <bits/stdc++.h>
using namespace std;
FILE *fin = fopen ("lca.in", "r"), *fout = fopen ("lca.out", "w");
int euler;
const int MAXN = 1e5, MAXK = 20;
int a[MAXN * 2 + 1], rmq[MAXN * 2][MAXK];
int apar[MAXN + 1];
int lg[2 * MAXN + 1];
vector <int> gr[MAXN + 1];
void dfs (int nod, int tata) {
a[++euler] = nod;
apar[nod] = euler;
for (auto fiu : gr[nod]) {
if (fiu != tata) {
dfs (fiu, nod);
a[++euler] = nod;
}
}
}
void make_rmq () {
int i, k;
for (i = 1; i <= euler; i++)
rmq[i][0] = a[i];
for (i = 2; i <= euler; i++)
lg[i] = lg[i / 2] + 1;
for (k = 1; (1 << k) <= euler; k++) {
for (i = 1; i <= euler; i++) {
rmq[i][k] = min (rmq[i][k - 1], rmq[min (euler, i + (1 << (k - 1)))][k - 1]);
}
}
}
int query (int x, int y) {
int l, r, k;
l = apar[x];
r = apar[y];
if (l > r)
swap (l, r);
k = lg[r - l + 1];
return min (rmq[l][k], rmq[r - (1 << k) + 1][k]);
}
int main() {
int n, m, x, y, i;
fscanf (fin, "%d%d", &n, &m);
for (i = 2; i <= n; i++) {
fscanf (fin, "%d", &x);
gr[x].push_back (i);
gr[i].push_back (x);
}
dfs (1, -1);
make_rmq ();
while (m--) {
fscanf (fin, "%d%d", &x, &y);
fprintf (fout, "%d\n", query (x, y));
}
return 0;
}