Pagini recente » Cod sursa (job #2930887) | Cod sursa (job #420313) | Cod sursa (job #197999) | Cod sursa (job #72823) | Cod sursa (job #1850399)
#include <fstream>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int n,m,arb[100101],start[100010],jump[100010],sol[30][300010],viz[100010],o;
void read ()
{ int q;
cin>>n>>m;
for(int i=2;i<=n;i++)
{
cin>>q;
arb[i]=i;
jump[i]=start[q];
start[q]=i;
}
}
void dfs (int nod)
{
sol[0][++o]=nod;
int x=start[nod];
while(x)
{
if(viz[arb[x]]==0)
{
viz[arb[x]]=viz[nod]+1;
dfs(arb[x]);
sol[0][++o]=nod;
} x=jump[x];
}
}
void init ()
{
for(int i=1;i<=o;i++)
arb[sol[0][i]]=i;
}
void construct ()
{
int lim=0,r=1,h=1;
while(r<=o) lim++,r*=2; r/=2; lim--;
for(int i=1;i<=lim;++i) {
for(int j=1;j<=o;j++)
{
int x1=viz[sol[i-1][j]],x2=viz[sol[i-1][j+h]];
if(x1<x2) sol[i][j]=sol[i-1][j]; else sol[i][j]=sol[i-1][j+h];
} h*=2; }
}
void solve_here ()
{ int a,b;
for(int i=1;i<=m;i++)
{
cin>>a>>b;
a=arb[a]; b=arb[b]; if(a>b) swap(a,b);
int lim=0,r=1;
while(r<=b-a+1) r*=2,lim++; lim--; r/=2;
int x1=sol[lim][a],x2=sol[lim][b-r+1];
if(viz[x1]<viz[x2]) cout<<x1; else cout<<x2; cout<<"\n";
}
}
int main()
{
read();
dfs(1);
init();
construct();
solve_here();
cin.close();
cout.close();
return 0;
}