Pagini recente » Cod sursa (job #2919742) | Cod sursa (job #348559) | Cod sursa (job #2850553) | Cod sursa (job #1851627) | Cod sursa (job #886637)
Cod sursa(job #886637)
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int MAX_N = 100100;
const int MAX_M = 2000000;
const int MAX_LOG = 20;
int N, M;
vector<int> tree[MAX_N];
int father[MAX_N];
int euler_position[MAX_N];
int euler_node[2 * MAX_N];
int euler_depth[2 * MAX_N];
int euler_length = 0;
int log2[2 * MAX_N];
int rmq[2 * MAX_N][MAX_LOG];
void cross_euler(int node, int depth);
void euler_crossing(int node, int depth);
void compute_rmq();
int lca(int a, int b);
int main() {
fin >> N >> M;
for (int i = 2; i <= N; ++i) {
fin >> father[i];
tree[father[i]].push_back(i);
}
euler_crossing(1, 0);
compute_rmq();
int a, b;
for (int i = 1; i <= M; ++i) {
fin >> a >> b;
fout << lca(a, b) << '\n';
}
return 0;
}
inline void cross_euler(int node, int depth) {
++euler_length;
rmq[euler_length][0] = euler_length;
euler_node[euler_length] = node;
euler_depth[euler_length] = depth;
}
void euler_crossing(int node, int depth) {
cross_euler(node, depth);
euler_position[node] = euler_length;
for (vector<int>::iterator it = tree[node].begin(); it != tree[node].end(); ++it) {
euler_crossing(*it, depth + 1);
cross_euler(node, depth);
}
}
void compute_rmq() {
for (int l = 1; (1 << l) <= euler_length; ++l) {
for (int i = 1; i + (1 << l) - 1 <= euler_length; ++i) {
if (euler_depth[rmq[i][l - 1]] <= euler_depth[rmq[i + (1 << (l - 1))][l - 1]]) {
rmq[i][l] = rmq[i][l - 1];
} else {
rmq[i][l] = rmq[i + (1 << (l - 1))][l - 1];
}
}
}
log2[1] = 0;
for (int i = 2; i <= euler_length; ++i) {
log2[i] = log2[i / 2] + 1;
}
}
inline int lca(int a, int b) {
int lo = euler_position[a];
int hi = euler_position[b];
if (lo > hi) swap(lo, hi);
int k = log2[hi - lo + 1];
if (euler_depth[rmq[lo][k]] <= euler_depth[rmq[hi - (1 << k) + 1][k]]) {
return euler_node[rmq[lo][k]];
} else {
return euler_node[rmq[hi - (1 << k) + 1][k]];
}
}