Pagini recente » Cod sursa (job #1331636) | Cod sursa (job #1352421) | Cod sursa (job #504843) | Cod sursa (job #1884649) | Cod sursa (job #1849863)
#include <fstream>
#include<climits>
using namespace std;
ifstream cin ("lca.in");
ofstream cout ("lca.out");
int arb[500010],jump[100010],start[100010],n,m,euler[100010],viz[100010],o,poz,key,where[100010],a,b;
void read ()
{ int q; viz[0]=INT_MAX;
cin>>n>>m;
for(int i=2;i<=n;i++)
{
cin>>q;
jump[i]=start[q];
start[q]=i;
arb[i]=i;
}
}
void dfs (int nod)
{ euler[++o]=nod;
int x=start[nod];
while(x)
{
if(viz[arb[x]]==0)
{ viz[arb[x]]=viz[nod]+1;
dfs(arb[x]);
euler[++o]=nod;
} x=jump[x];
}
}
void up_date (int st,int dr,int nod)
{
if(st>=poz && dr<=poz)
arb[nod]=key;
else
{
int mij=(st+dr)/2;
if(poz<=mij) up_date(st,mij,nod*2);
else up_date(mij+1,dr,nod*2+1);
if(viz[arb[nod*2]]<viz[arb[nod*2+1]]) arb[nod]=arb[nod*2]; else arb[nod]=arb[nod*2+1];
}
}
void make_arbore ()
{
for(int i=1;i<=n;i++) arb[i]=0;
for(int i=1;i<=o;i++)
{ poz=i; key=euler[i]; if(where[euler[i]]==0) where[euler[i]]=i;
up_date(1,o,1);
}
}
int find_out (int st,int dr,int nod)
{
if(a<=st && b>=dr)
return arb[nod];
int mij=(st+dr)/2,x1=0,x2=0;
if(a<=mij) x1=find_out(st,mij,nod*2);
if(b>mij) x2=find_out(mij+1,dr,nod*2+1);
if(viz[x1]<viz[x2]) return x1;
else return x2;
}
void solve_here ()
{
for(int i=1;i<=m;i++)
{
cin>>a>>b; a=where[a]; b=where[b];
if(a>b) swap(a,b);
cout<<find_out(1,o,1)<<"\n";
}
}
int main()
{
read();
dfs(1);
make_arbore();
solve_here();
cin.close();
cout.close();
return 0;
}