Pagini recente » Cod sursa (job #1449792) | Cod sursa (job #3312485)
#include<iostream>
#include<fstream>
#include<vector>
using namespace std;
ifstream in("lca.in");
ofstream out("lca.out");
struct node {
int index;
int height;
};
vector<node> euler;
vector<vector<int>> graph;
vector<int> first_index;
int n, m;
void read(){
in>>n>>m;
graph.resize(n+1);
int father;
for (int i = 2; i<=n; i++){
in>>father;
graph[i].push_back(father);
graph[father].push_back(i);
}
}
void dfs(int here, int father, int depth) {
euler.push_back({here, depth});
for(int neighbour: graph[here]) {
if (neighbour == father) continue;
dfs(neighbour, here, depth+1);
euler.push_back({here, depth});
}
}
vector<node> tree;
void build_tree_rec(int index, int l, int r) {
if(l == r) {
tree[index] = euler[l];
} else {
int m = (l+r)/2;
build_tree_rec(index*2, l, m);
build_tree_rec(index*2+1, m+1, r);
node left = tree[index*2];
node right = tree[index*2 + 1];
if (left.height < right.height) {
tree[index] = left;
} else {
tree[index] = right;
}
}
}
void build_tree() {
tree.resize(4 * euler.size());
build_tree_rec(1, 0, euler.size()-1);
}
node query_tree_rec(int index, int l, int r, int ql, int qr) {
if (l>= ql && r <= qr) {
return tree[index];
} else {
int m = (l+r)/2;
node result = {-1, (int) 1e9};
if(ql <= m) {
node k = query_tree_rec(index*2, l, m, ql, qr);
if (k.height < result.height) result = k;
}
if (qr > m) {
node k = query_tree_rec(index*2+1, m+1, r, ql, qr);
if (k.height < result.height) result = k;
}
return result;
}
}
void compute_first_indices() {
first_index.resize(n+1, -1);
for(int i = 0 ;i<euler.size(); i++){
node here = euler[i];
if (first_index[here.index] == -1) {
first_index[here.index] = i;
}
}
}
int lca(int a, int b){
int index_a = first_index[a];
int index_b = first_index[b];
if (index_a > index_b) swap(index_a, index_b);
node result = query_tree_rec(1, 0, euler.size()-1, index_a, index_b);
return result.index;
}
int main(){
read();
dfs(1, 0, 0);
build_tree();
compute_first_indices();
int a, b;
for(int i = 0; i<m;i++){
in>>a>>b;
out<<lca(a, b)<<"\n";
}
return 0;
}