Pagini recente » Cod sursa (job #1067310) | Cod sursa (job #2121054) | Cod sursa (job #1480117) | Cod sursa (job #128388) | Cod sursa (job #2084642)
#include <bits/stdc++.h>
#define DM 100005
#define pb push_back
#define pii pair<int,int>
#define x first
#define y second
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
int n,m,lg,a,b;
vector<int>fiu[DM];
int niv[DM];
int parinte[DM],parinte2[DM];
vector<int>aux;
void construct(int nod){
int sz = aux.size();
parinte2[nod]=(sz-lg>=0?aux[sz-lg]:0);
aux.pb(nod);
for(auto i:fiu[nod])
construct(i);
aux.pop_back();
}
void dfs(int nod,int currNiv){
niv[nod]=currNiv;
lg=max(lg,currNiv);
for(auto i:fiu[nod])
dfs(i,currNiv+1);
}
pii makeSameLevel(int a,int b){
if(niv[a]<niv[b]) swap(a,b);
int aux = a;
while(niv[aux]!=niv[b]){
if(niv[aux]-niv[b]>=lg)
aux=parinte2[aux];
else
aux=parinte[aux];
}
return {aux,b};
}
void lca(int a,int b){
pii aux = makeSameLevel(a,b);
int aux1=aux.first,aux2=aux.second;
int level = niv[aux1];
while(aux1!=aux2){
if(level>lg){
if(parinte2[aux1]==parinte2[aux2]){
for(int i=1;i<=lg && aux1!=aux2;++i){
aux1=parinte[aux1];
aux2=parinte[aux2];
}
}
else{
aux1=parinte2[aux1];
aux2=parinte2[aux2];
level-=lg;
}
}
else{
aux1=parinte[aux1];
aux2=parinte[aux2];
level-=1;
}
}
fout<<aux1<<'\n';
}
int main()
{
fin>>n>>m;
for(int i=2;i<=n;++i){
fin>>a;
fiu[a].pb(i);
parinte[i]=a;
}
dfs(1,1);
lg=sqrt(lg);
construct(1);
for(int i=1;i<=m;++i){
fin>>a>>b;
lca(a,b);
}
return 0;
}