Pagini recente » Borderou de evaluare (job #778891) | Cod sursa (job #2504665) | Cod sursa (job #685350) | Cod sursa (job #3146513) | Cod sursa (job #3144183)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N_MAX = 1e5;
const int EULER_DIM_MAX = 2 * N_MAX - 1;
const int LOG_MAX = 18;
template<typename T>
class OptimizedSparseTable{
private:
T table[LOG_MAX][EULER_DIM_MAX];
char lb[N_MAX + 1];
T (* merge)(const T&, const T&);
public:
OptimizedSparseTable(T (* func)(const T&, const T&)) : merge(func){}
void build(int n, T v[]){
lb[1] = 0;
for(int i = 2; i <= n; ++i)
lb[i] = lb[i / 2] + 1;
for(int i = 0; i < n; ++i)
table[0][i] = v[i];
for(int e = 1; e < LOG_MAX; ++e)
for(int i = 0; i + (1 << e) - 1 < n; ++i)
table[e][i] = merge(table[e - 1][i], table[e - 1][i + (1 << (e - 1))]);
}
T query(int left, int right){
int e = lb[right - left + 1];
return merge(table[e][left], table[e][right - (1 << e) + 1]);
}
void print(int n){
for(int e = 0; e < LOG_MAX; ++e){
for(int i = 0; i < n; ++i)
fout << table[e][i] << ' ';
fout.put('\n');
}
}
};
int euler[EULER_DIM_MAX], eulerIndex;
int first[N_MAX], level[N_MAX];
vector<int> children[N_MAX];
void TourOfTree(int node){
euler[eulerIndex] = node;
first[node] = eulerIndex;
++eulerIndex;
for(auto child: children[node]){
TourOfTree(child);
euler[eulerIndex] = node;
++eulerIndex;
}
}
void ComputeLevel(int node, int lvl){
level[node] = lvl;
for(auto child: children[node])
ComputeLevel(child, lvl + 1);
}
int min(const int& a, const int& b){
return (level[a] < level[b]) ? a : b;
}
OptimizedSparseTable<int> rmq(min);
int LCA(int a, int b){
if(first[a] > first[b])
swap(a, b);
return rmq.query(first[a], first[b]);
}
int main(){
int n, queries, parent;
fin >> n >> queries;
for(int i = 1; i < n; ++i){
fin >> parent;
children[parent - 1].push_back(i);
}
eulerIndex = 0;
TourOfTree(0);
ComputeLevel(0, 0);
rmq.build(2 * n - 1, euler);
for(int i = 0; i < queries; ++i){
fin >> n >> parent;
fout << LCA(n - 1, parent - 1) + 1 << '\n';
}
fin.close();
fout.close();
return 0;
}