Pagini recente » Cod sursa (job #1107188) | Cod sursa (job #2466046) | Cod sursa (job #891360) | Cod sursa (job #937000) | Cod sursa (job #2503860)
#include <cstdio>
#include <vector>
#include <algorithm>
const int MAX_N = 100000;
std::vector<int> g[1 + MAX_N];
int rmq[1 + 2 * MAX_N][20];
int euler[1 + 2 * MAX_N], k;
int level[1 + 2 * MAX_N];
int first[1 + MAX_N];
void dfs(int node, int dad, int lev) {
euler[++k] = node;
level[k] = lev;
first[node] = k;
for (auto u : g[node]) {
if (u != dad) {
dfs(u, node, lev + 1);
euler[++k] = node;
level[k] = lev;
}
}
}
int exp2(int x) {
int k = -1;
for (int i = 1; i <= x; i += i) {
k++;
}
return k;
}
int lca(int x, int y) {
x = first[x];
y = first[y];
if (x > y) {
int aux = x;
x = y;
y = aux;
}
int lg = exp2(y - x + 1);
if (level[rmq[x][lg]] < level[rmq[y - (1 << lg) + 1][lg]])
return euler[rmq[x][lg]];
else
return euler[rmq[y - (1 << lg) + 1][lg]];
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
int n, m;
scanf("%d%d", &n, &m);
for (int i = 2; i <= n; i++) {
int x;
scanf("%d", &x);
g[x].push_back(i);
g[i].push_back(x);
}
dfs(1, 0, 0);
for (int i = 1; i <= k; i++) {
rmq[i][0] = i;
}
for (int j = 1; (1 << j) <= k; j++) {
for (int i = 1; i + (1 << j) - 1 <= k; i++) {
if (level[rmq[i][j - 1]] < level[rmq[i + (1 << (j - 1))][j - 1]])
rmq[i][j] = rmq[i][j - 1];
else
rmq[i][j] = rmq[i + (1 << (j - 1))][j - 1];
}
}
for (int i = 1; i <= m; i++) {
int x, y;
scanf("%d%d", &x, &y);
printf("%d\n", lca(x, y));
}
return 0;
}