Pagini recente » Cod sursa (job #64633) | Cod sursa (job #862126) | Cod sursa (job #1123678) | Cod sursa (job #1795161) | Cod sursa (job #3144170)
#include <fstream>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int N_MAX = 1e5;
const int LOG_MAX = 17;
template<typename T>
class AncestorsSparseTable{
private:
T table[LOG_MAX][N_MAX];
public:
void build(int n, ifstream& fin){
T aux{};
table[0][1] = aux;
for(int i = 2; i <= n; ++i){
fin >> table[0][i];
}
for(int e = 1; e < LOG_MAX; ++e)
for(int i = 1; i <= n; ++i)
table[e][i] = table[e - 1][table[e - 1][i]];
}
T query(int e, int i){
return table[e][i];
}
void print(int n){
for(int e = 0; e < LOG_MAX; ++e){
for(int i = 1; i <= n; ++i)
fout << table[e][i] << ' ';
fout.put('\n');
}
}
};
AncestorsSparseTable<int> ancestors;
int lvl[N_MAX]{};
char lb[N_MAX];
void PrecomputeLog2(int n){
lb[1] = 0;
for(int i = 2; i < n; ++i)
lb[i] = lb[i / 2] + 1;
}
int level(int node){
if(node <= 1)
lvl[node] = 0;
else if(!lvl[node])
lvl[node] = level(ancestors.query(0, node)) + 1;
return lvl[node];
}
int LCA(int a, int b){
if(level(a) != level(b)){
if(level(a) > level(b))
swap(a, b);
for(int e = lb[level(a) - level(b)] - 1; e >= 0; --e){
if(level(a) < level(ancestors.query(e, b)))
b = ancestors.query(e, b);
}
b = ancestors.query(0, b);
}
for(int e = lb[level(a)]; e >= 0; --e)
if(ancestors.query(e, a) != ancestors.query(e, b)){
a = ancestors.query(e, a);
b = ancestors.query(e, b);
}
if(a != b)
a = ancestors.query(0, a);
return a;
}
int main(){
int n, queries, a, b;
fin >> n >> queries;
PrecomputeLog2(n);
ancestors.build(n, fin);
for(int i = 0; i < queries; ++i){
fin >> a >> b;
fout << LCA(a, b) << '\n';
}
fin.close();
fout.close();
return 0;
}