Pagini recente » Cod sursa (job #95351) | Cod sursa (job #427979) | Cod sursa (job #3337799) | Cod sursa (job #3314647) | Cod sursa (job #3311263)
#include <bits/stdc++.h>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
const int LOGMAX=15;
struct rmq{
vector<vector<int> > mat;
vector<int> lg;
rmq(vector<int> &v, int n)
:mat(LOGMAX+5, vector<int>(n+5, 0)), lg(n+1)
{
build_log(n);
build_rmq(v, n);
}
void build_log(int n){
lg[1]=0;
for(int i=2;i<=n;i++){
lg[i]=lg[i/2]+1;
}
}
void build_rmq(vector<int> &v, int n){
for(int i=1;i<=n;i++){
mat[0][i]=i;
}
for(int i=1;i<=lg[n];i++){
for(int j=1;j+(1<<i)-1<=n;j++){
if(v[mat[i-1][j]]<=v[mat[i-1][j+(1<<(i-1))]]){
mat[i][j]=mat[i-1][j];
}else{
mat[i][j]=mat[i-1][j+(1<<(i-1))];
}
}
}
}
int query(vector<int> &v, int L, int R){
int dist=lg[R-L+1];
if(v[mat[dist][L]]<v[mat[dist][R-(1<<dist)+1]]){
return mat[dist][L];
}else{
return mat[dist][R-(1<<dist)+1];
}
}
};
vector<bool> vizitat;
vector<int> euler, first_ap, nivel;
vector<vector<int> > graph;
void dfs(int nod, int level){
vizitat[nod]=1;
euler.push_back(nod);
nivel.push_back(level);
for(auto it:graph[nod]){
if(vizitat[it]==0){
dfs(it, level+1);
nivel.push_back(level);
euler.push_back(nod);
}
}
}
int main(){
int n, q;
fin>>n>>q;
vector<int> test;
vizitat.resize(n+1);
graph.resize(n+1);
first_ap.resize(n+1);
for(int i=2;i<=n;i++){
int val;
fin>>val;
graph[val].push_back(i);
graph[i].push_back(val);
}
euler.push_back(0);
nivel.push_back(0);
dfs(1, 0);
for(int i=1;i<euler.size();i++){
if(first_ap[euler[i]]==0){
first_ap[euler[i]]=i;
}
}
rmq ans(nivel, nivel.size());
for(int i=1;i<=q;i++){
int l, r;
fin>>l>>r;
if(l>r){
swap(l,r);
}
l=first_ap[l];
r=first_ap[r];
fout<<euler[ans.query(nivel, l, r)]<<'\n';
}
}