Cod sursa(job #526974)

Utilizator BlaugranasEnal Gemaledin Blaugranas Data 30 ianuarie 2011 09:51:39
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.06 kb
#include<stdio.h>
#define N 100001
long n,m,a[N],x,y,i,j,p[N][20],l[N];

void init(long n,long a[N],long p[N][20])
{long i,j;
for(i=0;i<=n;i++)
      {for(j=0;1<<j<=n;j++)
             p[i][j]=-1;}
for(i=1;i<=n;i++)
      p[i][0]=a[i];
for(j=1;(1<<j)<=n;j++)
      {for(i=0;i<=n;i++)
      if(p[i][j-1]!=-1)
             p[i][j]=p[p[i][j-1]][j-1];}}

long lca(long n,long p[N][20],long a[N],long l[N],long x,long y)
{long i,tmp,log;
if(l[x]<l[y])
      {tmp=x;
      x=y;
      y=tmp;}
for(log=1;1<<log<=l[x];log++);
log--;
for(i=log;i>=0;i--)
if(l[x]-(1<<i)>=l[y])
      x=p[x][i];
if(x==y)
      return x;
for(i=log;i>=0;i--)
if(p[x][i]!=-1&&p[x][i]!=p[y][i])
      {x=p[x][i];
      y=p[y][i];}
return a[x];}

int main()
{freopen("lca.in","r",stdin);
freopen("lca.out","w",stdout);
scanf("%ld%ld\n",&n,&m);
l[1]=1;
for(i=2;i<=n;i++)
      {scanf("%ld",&a[i]);
      l[i]=l[a[i]]+1;}
init(n,a,p);
for(j=1;j<=m;j++)
      {scanf("%ld%ld\n",&x,&y);
      printf("%ld\n",lca(n,p,a,l,x,y));}
fclose(stdin);
fclose(stdout);
return 0;}