Pagini recente » Cod sursa (job #1793639) | Cod sursa (job #2619062) | Cod sursa (job #1944888) | Cod sursa (job #2502583) | Cod sursa (job #2944310)
#include <fstream>
#include <vector>
using namespace std;
ifstream cin("lca.in");
ofstream cout("lca.out");
int tata[100005],poz=1,n;
vector<int>fii[100005];
pair<int,int>pu[100005];
int grad[100005];
int v[300005];
int rmq[20][300005];
int lg2[300005];
void euler(int nod)
{
pu[nod].first=poz;
v[poz]=nod;
for(int i=0;i<fii[nod].size();i++)
{
poz++;
grad[fii[nod][i]]=grad[nod]+1;
euler(fii[nod][i]);
v[poz]=nod;
}
pu[nod].second=poz;
poz++;
}
void build()
{
for(int i=1;i<=poz;i++)
rmq[0][i]=v[i];
for(int i=1;i<=lg2[poz];i++)
{
for(int j=1;j<=poz-(1<<i)+1;j++)
{
if(grad[rmq[i-1][j]]<=grad[rmq[i-1][j+(1<<(i-1))]])
rmq[i][j]=rmq[i-1][j];
else
rmq[i][j]=rmq[i-1][j+(1<<(i-1))];
}
}
}
int fct(int a,int b)
{
int dif=b-a+1;
if(grad[rmq[lg2[dif]][a]]<=grad[rmq[lg2[dif]][b-(1<<lg2[dif])+1]])
return rmq[lg2[dif]][a];
return rmq[lg2[dif]][b-(1<<lg2[dif])+1];
}
int query(int a,int b)
{
if(pu[a].first>pu[b].first)
swap(a,b);
if(pu[a].second>pu[b].second)
return a;
else
return fct(pu[a].second,pu[b].first);
}
int main()
{
for(int i=2;i<300000;i++)
lg2[i]=lg2[i/2]+1;
int m;
cin>>n>>m;
for(int i=2;i<=n;i++)
{
cin>>tata[i];
fii[tata[i]].push_back(i);
}
euler(1);
build();
for(int i=0;i<m;i++)
{
int a,b;
cin>>a>>b;
cout<<query(a,b)<<'\n';
}
return 0;
}