Pagini recente » Cod sursa (job #2177345) | Cod sursa (job #1626515) | Cod sursa (job #1305098) | Cod sursa (job #3219856) | Cod sursa (job #1639409)
#include <fstream>
#include <cmath>
#include <vector>
using namespace std;
vector <int> G[10005];
int n, q, ancestor[18][100005], depth[100005], log_n;
bool used[100005];
void dfs(int node, int step) {
used[node] = true;
for(auto nxt: G[node]) {
if(used[nxt]) {
continue;
}
dfs(nxt, step + 1);
depth[nxt] = step;
}
}
inline void ancestor_init() {
log_n = log2(n) + 1;
for(int i = 1; i <= log_n; ++i) {
for(int j = 1; j <= n; ++j) {
ancestor[i][j] = ancestor[i - 1][ancestor[i - 1][j]];
}
}
}
inline void equalise(int &node_deep, int &node_norm) {
if(depth[node_deep] < depth[node_norm]) {
swap(node_deep, node_norm);
}
int dist = depth[node_deep] - depth[node_norm];
for(int j = 0; j <= log_n; ++j) {
int bitmask = (1 << j);
if(dist & bitmask) {
node_deep = ancestor[j][node_deep];
}
}
}
inline int lca(int node1, int node2) {
if(node1 == node2) {
return node1;
}
for(int j = log_n; j >= 0; --j) {
if(ancestor[j][node1] != ancestor[j][node2] and ancestor[j][node1]) {
node1 = ancestor[j][node1];
node2 = ancestor[j][node2];
}
}
return ancestor[0][node1];
}
int main() {
freopen("lca.in", "r", stdin);
freopen("lca.out", "w", stdout);
scanf("%d%d", &n, &q);
ancestor[0][1] = 1;
for(int i = 2; i <= n; ++i) {
scanf("%d", &ancestor[0][i]);
G[ancestor[0][i]].push_back(i);
}
dfs(1, 0);
ancestor_init();
for(int i = 1; i <= q; ++i) {
int node1, node2;
scanf("%d%d", &node1, &node2);
equalise(node1, node2);
printf("%d\n", lca(node1, node2));
}
return 0;
}