Pagini recente » Cod sursa (job #1298049) | Diferente pentru runda/w0 intre reviziile 1 si 2 | Profil PostMalone | Sandbox | Cod sursa (job #408889)
Cod sursa(job #408889)
#include<stdio.h>
#include<vector>
using namespace std;
#define Nmax 100010
#define Emax 300010
#define log 20
int N,t[Nmax],niv[Nmax];
vector <int> l[Nmax];
int E[Emax],Ne[Emax],F[Nmax],Nr;
int Rmq[log][Emax],lg[Emax];
int min(int x,int y)
{return (x<y?x:y);}
int lca(int A,int B)
{
A=F[A]; B=F[B];
int C,dist,k,Sol;
if (A>B)
C=A, A=B, B=C;
dist=B-A+1;
k=lg[dist];
Sol=Rmq[k][A];
if (Ne[ Sol ] > Ne[ Rmq[k][B+1-(1<<k)] ])
Sol = Rmq[k][B-(1<<k)];
return (E[Sol]);
}
void rmq()
{
for(int i=2;i<=Nr;++i)
lg[i]=lg[i>>1]+1;
for(int i=1;i<=Nr;++i)
{
Rmq[0][i]=i;
Ne[i]=niv[E[i]];
}
for(int i=1;(1<<i)<=Nr;++i)
for(int j=1,p=(1<<(i-1)); j+(1<<i)<=Nr ;++j)
{
Rmq[i][j]=Rmq[i-1][j];
if (Ne[ Rmq[i][j] ] > Ne[ Rmq[i-1][j+p] ])
Rmq[i][j]=Rmq[i-1][j+p];
}
}
void DF(int k)
{
E[++Nr]=k;
F[k]=Nr;
for(int i=0;i<(int)l[k].size();++i)
{
niv[ l[k][i] ]=niv[k]+1;
DF( l[k][i] );
E[++Nr]=k;
}
}
int main()
{
int M,a,b;
freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%d%d",&N,&M);
for(int i=2;i<=N;++i)
{
scanf("%d",&t[i]);
l[ t[i] ].push_back(i);
}
DF(1);
rmq();
for(int i=1;i<=M;++i)
{
scanf("%d %d",&a,&b);
printf("%d\n",lca(a,b));
}
return 0;
}