Pagini recente » Rating Oprea Ioan-Cristian (OpreaCristian) | Cod sursa (job #3181489) | Cod sursa (job #2055080)
#include <iostream>
#include <map>
#include <cstring>
#include <cstdlib>
#include <vector>
#define rad 2000
using namespace std;
int N,M;
vector<int> G[100005];
int euler[200005];
int RMQ[18][200005];
int fst[100005];
int lst[100005];
int dep[100005];
int eulsz;
int lg[200005];
int calceuler(int nod,int tata)
{
dep[nod]=1+dep[tata];
euler[++eulsz]=nod;
fst[nod]=eulsz;
for(auto it:G[nod])
{
if(it!=tata)
{
calceuler(it,nod);
euler[++eulsz]=nod;
}
}
lst[nod]=eulsz;
}
void prelca()
{
for(int i=2;i<=200000;i++)lg[i]=1+lg[i/2];
for(int i=1;i<=eulsz;i++)
{
RMQ[0][i]=euler[i];
}
for(int k=1;k<=17;k++)
{
for(int i=1;i<=eulsz;i++)
{
int b=i,a=i-(1<<(k-1));
if(a<=0)RMQ[k][i]=RMQ[k-1][i];
else
{
int nod1=RMQ[k-1][a],nod2=RMQ[k-1][b];
RMQ[k][i]=(dep[nod1]<dep[nod2] ? nod1:nod2);
}
}
}
}
int lca(int a,int b)
{
a=fst[a];b=fst[b];
if(b<a)swap(a,b);
int LG=lg[b-a+1];
return dep[RMQ[LG][b]]<dep[RMQ[LG][a+(1<<LG)-1]] ? RMQ[LG][b]:RMQ[LG][a+(1<<LG)-1];
}
int main() {
freopen("lca.in","r",stdin);cin.sync_with_stdio(false);cin.tie(0);
freopen("lca.out","w",stdout);cout.sync_with_stdio(false);cout.tie(0);
cin>>N>>M;
for(int i=2;i<=N;i++)
{
int x;
cin>>x;
G[x].push_back(i);
G[i].push_back(x);
}
calceuler(1,0);
prelca();
for(int i=1;i<=M;i++)
{
int x,y;
cin>>x>>y;
cout<<lca(x,y)<<"\n";
}
return 0;
}