Pagini recente » Istoria paginii utilizator/liviuu23 | Cod sursa (job #3214640) | Cod sursa (job #2740943) | Cod sursa (job #752720) | Cod sursa (job #2017197)
#include <fstream>
#include <vector>
#define DIM 100001
using namespace std;
ifstream fi("lca.in");
ofstream fo("lca.out");
int n,m;
int E[5*DIM],L[5*DIM],H[DIM],nre;
int VIZ[DIM];
vector<int> V[DIM];
int RMQ[20][5*DIM],LG[5*DIM];
void euler(int v,int l)
{
VIZ[v]=1;
nre++;
E[nre]=v,L[nre]=l;
if(!H[v]) H[v]=nre;
for(int i=0;i<V[v].size();i++)
{
int to=V[v][i];
if(!VIZ[to])
{
euler(to,l+1);
nre++;
E[nre]=v,L[nre]=l;
}
}
}
void initRMQ()
{
for(int i=1;i<=nre;i++)
RMQ[0][i]=i;
for(int i=1;(1<<i)<=nre;i++)
for(int j=1;j<=nre-(1<<i)+1;j++)
if(L[RMQ[i-1][j]]<L[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 main()
{
fi>>n>>m;
for(int i=2;i<=n;i++)
{
int p;
fi>>p;
V[p].push_back(i);
V[i].push_back(p);
}
euler(1,1);
initRMQ();
//precalculam logaritm
for(int i=2;i<=nre;i++)
LG[i]=LG[i/2]+1;
for(int i=1;i<=m;i++)
{
int a,b;
fi>>a>>b;
a=H[a],b=H[b];
int k=LG[b-a+1];
if(L[RMQ[k][a]]<L[RMQ[k][b-(1<<k)+1]])
fo<<E[RMQ[k][a]]<<"\n";
else
fo<<E[RMQ[k][b-(1<<k)+1]]<<"\n";
}
fi.close();
fo.close();
return 0;
}