Pagini recente » Cod sursa (job #525430) | Cod sursa (job #2587448) | Cod sursa (job #589802) | Cod sursa (job #417435) | Cod sursa (job #3175992)
#include <iostream>
#include <fstream>
#include <vector>
#define pb push_back
#define fi first
#define se second
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
typedef pair<int, int> pii;
const int Nmax=1e5+5;
int n, m, f[Nmax];
vector<int> ad[Nmax], lg;
vector<pii> euler, st[20];
void dfs(int nod, int p, int h){
f[nod]=euler.size();
euler.pb({h, nod});
for (auto it:ad[nod])
if (it!=p){
dfs(it, nod, h+1);
euler.pb({h, nod});
}
}
inline void build_sparse_table(){
for (int i=0; i<euler.size(); i++)
st[0].pb(euler[i]);
int p=2, ind=1;
while (p<=euler.size()){
for (int i=0; i+p<=euler.size(); i++)
st[ind].pb(min(st[ind-1][i], st[ind-1][i+p/2]));
p*=2; ind++;
}
}
inline void build_lg(){
lg.resize(euler.size()+1);
lg[1]=0;
for (int i=2; i<=euler.size(); i++)
lg[i]=lg[i/2]+1;
}
int lca(int x, int y){
if (f[x]>f[y]) swap(x, y);
int lg2=lg[f[y]-f[x]+1];
return min(st[lg2][f[x]], st[lg2][f[y]-(1<<lg2)+1]).se;
}
int main(){
fin>>n>>m;
int nr;
for (int i=1; i<n; i++){
fin>>nr; nr--;
ad[i].pb(nr);
ad[nr].pb(i);
}
dfs(0, -1, 0);
build_sparse_table();
build_lg();
int x, y;
for (int i=1; i<=m; i++){
fin>>x>>y;
x--; y--;
fout<<lca(x, y)+1<<'\n';
}
return 0;
}