Pagini recente » Cod sursa (job #2307632) | Cod sursa (job #2933143) | Cod sursa (job #269047) | Cod sursa (job #1265384) | Cod sursa (job #3276007)
#include <bits/stdc++.h>
#define L 100005
#define S 18
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n, q;
vector <int> G[L];
int firstAp[L], lev[L], p2[2 * L], rmq[S][2 * L], euler[2 * L], eulerSize;
void dfsEuler(int node, int prev) {
for (auto it : G[node]) {
if (it == prev)
continue;
euler[++eulerSize] = node;
lev[it] = lev[node] + 1;
dfsEuler(it, node);
}
euler[++eulerSize] = node;
}
int minLev(int x, int y) {
if (lev[x] < lev[y])
return x;
return y;
}
void computeLCA() {
lev[1] = 1;
dfsEuler(1, 0);
for (int i = 1; i <= eulerSize; i++)
if (firstAp[euler[i]] == 0)
firstAp[euler[i]] = i;
int p = 0;
for (int i = 1; i <= 30; i++) {
if ((1 << (p + 1)) <= i)
p++;
p2[i] = p;
}
for (int i = 1; i <= eulerSize; i++)
rmq[0][i] = euler[i];
for (int bit = 1; bit < S; bit++)
for (int i = 1; i <= eulerSize - (1 << bit) + 1; i++)
rmq[bit][i] = minLev(rmq[bit - 1][i], rmq[bit - 1][i + (1 << (bit - 1))]);
}
int distBetween(int x, int y) {
x = firstAp[x];
y = firstAp[y];
int p = p2[y - x + 1];
return minLev(rmq[p][x], rmq[p][y - (1 << p) + 1]);
}
int main() {
fin >> n >> q;
for (int i = 1; i < n; i++) {
int a, b;
fin >> a;
b = i + 1;
G[a].push_back(b);
G[b].push_back(a);
}
computeLCA();
for (int i = 1; i <= q; i++) {
int a, b;
fin >> a >> b;
fout << distBetween(a, b) << "\n";
}
return 0;
}