Pagini recente » Borderou de evaluare (job #1503713) | Borderou de evaluare (job #2401412) | Borderou de evaluare (job #2013272) | Cod sursa (job #2607723) | Cod sursa (job #2507457)
#include <stdio.h>
#define N 100001
#define M 20
int n,m,tata[N],lev[N],prim[N],urm[N],x[2*N],poz[N],a[2*N][M],lg2[2*N],y[2*N];
void level(int i)
{
int j=tata[i];
if(lev[j]==0)
level(j);
lev[i]=lev[j]+1;
}
void initarb()
{
int i,j;
for(i=2;i<=n;i++)
{
j=tata[i];
urm[i]=prim[j];
prim[j]=i;
}
}
void dfs(int k)
{
int j;
x[m]=lev[k];y[m]=k;
poz[k]=m;
m++;
j=prim[k];
while(j)
{
dfs(j);
x[m]=lev[k];y[m]=k; m++;
j=urm[j];
}
}
void rmqi()
{
int i,j,k;
k=0;j=2;
for(i=1;i<m;i++)
{
if(i==j)
{
k++;j*=2;
}
lg2[i]=k;
}
for(i=1;i<m;i++)
a[i][0]=i;
for(j=1,k=1;j<m;j*=2,k++)
for(i=1;i<=m-j;i++)
if(x[a[i][k-1]]<=x[a[i+j][k-1]])
a[i][k]=a[i][k-1];
else
a[i][k]=a[i+j][k-1];
}
int min(int p,int q)
{
if(p<q)
return p;
else
return q;
}
int rmq(int i,int j)
{
int p=poz[i],q=poz[j],k,aux;
if(p>q)
{
aux=p;p=q;q=aux;
}
k=lg2[q-p+1];j=1<<k;
if(x[a[p][k]]<x[a[q-j+1][k]])
return y[a[p][k]];
else
return y[a[q-j+1][k]];
}
void main()
{
int i,j,k,r;
FILE *f,*g;
f=fopen("lca.in","r");
g=fopen("lca.out","w");
fscanf(f,"%d %d", &n,&r);
for(i=2;i<=n;i++)
fscanf(f,"%d",tata+i);
tata[1]=0;lev[1]=1;
for(i=2;i<=n;i++)
if(lev[i]==0)
level(i);
initarb();
m=1;
dfs(1);
rmqi();
for(i=1;i<=r;i++)
{
fscanf(f,"%d%d",&j,&k);
fprintf(g,"%d\n",rmq(j,k));
}
}