Pagini recente » Cod sursa (job #2522251) | Cod sursa (job #2659774) | Cod sursa (job #999363) | Cod sursa (job #1822781) | Cod sursa (job #2605560)
#include <iostream>
#include <fstream>
using namespace std;
ifstream in ("lca.in");
ofstream out ("lca.out");
const int N=100002;
int t[N],lst[N],vf[N],urm[N],nr,log2[2*N];
int ne,nivel[N],prima[N],e[2*N],rmq[18][2*N];
void adauga (int x, int y)
{
vf[++nr]=y;
urm[nr]=lst[x];
lst[x]=nr;
}
void euler (int nod)
{
e[++ne]=nod;
nivel[nod]=1+nivel[t[nod]];
prima[nod]=ne;
for (int p=lst[nod];p!=0;p=urm[p])
{
int y=vf[p];
if (prima[y]==0)
{
euler (y);
e[++ne]=nod;
}
}
}
void log (int n)
{
log2[1]=0;
for (int i=2;i<=2*n-1;i++)
{
log2[i]=log2[i/2]+1;
}
}
int lca (int x, int y)
{
int p=prima[x];
int q=prima[y];
if (p>q) swap(p,q);
int l=log2[q-p+1];
int st=rmq[l][p+(1<<l)-1];
int dr=rmq[l][q];
if (nivel[e[st]]<=nivel[e[dr]])
return e[st];
return e[dr];
}
int main()
{
int n,m,x,y;
in>>n>>m;
for (int i=2;i<=n;i++)
{
in>>x;
adauga (x,i);
t[i]=x;
}
log(n);
euler (1);
for (int i=1;i<=2*n-1;i++)
rmq[0][i]=i;
for (int i=1;(1<<i)<=2*n-1;i++)
{
for (int j=1<<i;j<=2*n-1;j++)
{
int st,dr;
st=rmq[i-1][j-(1<<(i-1))];
dr=rmq[i-1][j];
if (nivel[e[st]]>nivel[e[dr]])
rmq[i][j]=dr;
else rmq[i][j]=st;
//out<<rmq[i][j]<<' ';
}
//out<<'\n';
}
for (int i=1;i<=m;i++)
{
in>>x>>y;
out<<lca (x,y)<<'\n';
}
return 0;
}