Pagini recente » Cod sursa (job #459639) | Cod sursa (job #3306743) | Cod sursa (job #401783) | Cod sursa (job #152109) | Cod sursa (job #3308972)
#include <bits/stdc++.h>
using namespace std;
int h[100005], arb[100005], head[100005], parent[100005], heavyson[100005];
vector<int> child[100005];
int currchain;
int chain[100005];
int binlift[5][100005], lvlchain[100005], chainspar[100005];
void dfs(int u) {
arb[u] = 1;
for (int v : child[u]) {
dfs(v);
arb[u] += arb[v];
if (arb[v] > arb[heavyson[u]]) {
heavyson[u] = v;
}
}
}
void decomp(int u, bool newchain = 1, int chainpar = 0) {
if (newchain) {
chain[u] = ++currchain;
chainspar[chain[u]] = u;
head[u] = u;
binlift[0][chain[u]] = chainpar;
lvlchain[chain[u]] = lvlchain[chainpar] + 1;
}
else {
head[u] = head[parent[u]];
chain[u] = chain[parent[u]];
}
for (int v : child[u]) {
if (v == heavyson[u]) {
decomp(v, 0, 0);
}
else
decomp(v, 1, chain[u]);
}
}
void build() {
for (int b = 1; (1 << b) < currchain; b++) {
for (int i = 1; i <= currchain; i++) {
binlift[b][i] = binlift[b - 1][binlift[b - 1][i]];
}
}
}
int solve(int u, int v) {
int chainu = chain[u], chainv = chain[v];
if (chainu == chainv) {
//returnez nodul de mai sus
return h[u] < h[v] ? u : v;
}
if (lvlchain[chainu] > lvlchain[chainv]) {
int dif = lvlchain[chainu] - lvlchain[chainv] - 1;
for (int b = 0; b < 5; b++) {
if (dif & (1 << b)) {
chainu = binlift[b][chainu];
}
}
if (binlift[0][chainu] == chainv) {
u = parent[chainspar[chainu]];
return h[u] < h[v] ? u : v;
}
chainu = binlift[0][chainu];
}
else if (lvlchain[chainv] > lvlchain[chainu]) {
int dif = lvlchain[chainv] - lvlchain[chainu] - 1;
for (int b = 0; b < 5; b++) {
if (dif & (1 << b)) {
chainv = binlift[b][chainv];
}
}
if (binlift[0][chainv] == chainu) {
v = parent[chainspar[chainv]];
return h[u] < h[v] ? u : v;
}
chainv = binlift[0][chainv];
}
for (int b = 0; b < 5; b++) {
if (binlift[b][chainu] != binlift[b][chainv]) {
chainu = binlift[b][chainu];
chainv = binlift[b][chainv];
}
}
u = parent[chainspar[chainu]];
v = parent[chainspar[chainv]];
return h[u] < h[v] ? u : v;
}
int main() {
ifstream cin("lca.in");
ofstream cout("lca.out");
int n, q;
cin >> n >> q;
h[1] = 1;
for (int i = 2; i <= n; i++) {
int a;
cin >> a;
parent[i] = a;
child[a].push_back(i);
h[i] = h[a] + 1;
}
dfs(1);
decomp(1);
build();
//cout << chain[10] << " " << chain[3] << '\n';
//cout << lvlchain[chain[10]] << " " << lvlchain[chain[11]] << binlift[0][6] << '\n';
while (q--) {
int u, v;
cin >> u >> v;
cout << solve(u, v) << '\n';
}
return 0;
}