Cod sursa(job #712780)
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("lca.in");
ofstream fout("lca.out");
#define dim 200005
#define pb push_back
#define log 20
vector <int> v[dim];
int rmq[log][dim], n ,m,euler[dim],p,lung[dim],fiu[dim],lg[dim];
void read()
{
int i, x;
fin>> n >>m;
for(i=2;i<=n;++i)
{
fin>>x;
v[x].pb(i);
}
}
void dfs(int nod, int lev)
{
int i;
euler[++p]=nod;
lung[p]=lev;
fiu[nod]=p;
for(i=0;i<v[nod].size();++i)
{
dfs(v[nod][i],lev+1);
euler[++p]=nod;
lung[p]=lev;
}
}
void build_rmq()
{
int i, j;
for(i=2;i<=p;++i)
lg[i]=lg[i/2]+1;
for(i=1;i<=p;++i)
rmq[0][i]=i;
for(i=1;(1<<i)<p;++i)
for(j=1;j+(1<<i)<=p;++j)
if(lung[ rmq[i-1][j] ]<lung[ 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))];
}
void solve()
{
int x, y, val;
for(;m;--m)
{
fin>>x >>y;
x=fiu[x];
y=fiu[y];
if(x>y)
swap(x,y);
val=lg[y-x+1];
if(lung[ rmq[val][x] ] < lung[ rmq[val][y-(1<<val)+1] ])
fout<<euler[ rmq[val][x]]<<'\n';
else
fout<<euler[ rmq[val][y-(1<<val)+1] ] <<'\n';
}
}
int main()
{
read();
dfs(1,0);
build_rmq();
solve();
return 0;
}