Pagini recente » Cod sursa (job #3313622) | Borderou de evaluare (job #1524260) | Cod sursa (job #96849) | Cod sursa (job #1244153) | Cod sursa (job #3311202)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
struct binary_lifting{
struct node{
int depth, jump, parent;
};
vector<node> details;
binary_lifting(vector<vector<int>>& mat, int root)
:details(mat.size())
{
dfs(root, root, mat);
}
void dfs(int node, int parent, vector<vector<int>>& mat) {
int parent2=details[parent].jump;
details[node].depth=details[parent].depth+1;
if(details[parent].depth-details[parent2].depth==details[parent2].depth-details[details[parent2].jump].depth){
details[node].jump=details[parent2].jump;
}else{
details[node].jump=parent;
}
details[node].parent=parent;
for(int it:mat[node]){
if(it==parent)continue;
dfs(it,node,mat);
}
}
int kthParent(int node, int k){
while(k>0 and node>0){
if(details[node].depth-k<=details[details[node].jump].depth) {
k-=details[node].depth-details[details[node].jump].depth;
node=details[node].jump;
}else{
k--;
node=details[node].parent;
}
}
return node;
}
int lca(int node1, int node2){
if(details[node1].depth<details[node2].depth){
swap(node1,node2);
}
node1=kthParent(node1,details[node1].depth-details[node2].depth);
if(node1==node2){
return node1;
}
while(node1!=node2){
if(details[node1].jump==details[node2].jump){
node1=details[node1].parent;
node2=details[node2].parent;
}else{
node1=details[node1].jump;
node2=details[node2].jump;
}
}
return node1;
}
};
vector<vector<int> > mat;
int main(){
int n, q;
fin>>n>>q;
mat.resize(n+1);
for(int i=2;i<=n;i++){
int val;
fin>>val;
mat[val].push_back(i);
mat[i].push_back(val);
}
binary_lifting ans(mat, 1);
for(int i=1;i<=q;i++){
int nod1, nod2;
fin>>nod1>>nod2;
fout<<ans.lca(nod1,nod2)<<'\n';
}
}