Cod sursa(job #387850)

Utilizator irene_mFMI Irina Iancu irene_m Data 28 ianuarie 2010 16:56:52
Problema Lowest Common Ancestor Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.8 kb
#include <cstdio>
#define MaxN 100010
#define MaxL 25

struct muchie{
      int x;
      muchie *urm;
}     *G[MaxN];

int a[MaxN<<1],K,N,M,t[MaxN],h[MaxN<<1],poz[MaxN];
int rmq[MaxL][MaxN<<1];

void add(int tata,int fiu)
{
      muchie *q=new muchie;
      q->x=fiu; q->urm=G[tata]; G[tata]=q;
}

void read()
{
      int i;
      freopen("lca.in","r",stdin);
      scanf("%d%d",&N,&K);
      for(i=2;i<=N;i++)
      {
            scanf("%d",&t[i]);
            add(t[i],i);
      }
}

void euler(int nod,int n)
{
      muchie *q=new muchie;
      a[++M]=nod;
      poz[nod]=M;
      h[M]=n;
      for(q=G[nod];q;q=q->urm)
      {
            euler(q->x,n+1);
            a[++M]=nod;
            h[M]=n;
      }
}

int min(int a,int b)
{
      if(a<b)
            return a;
      return b;
}

void RMQ()
{
      int i,j;
      N=M;

      for(i=1;i<=N;i++)
            rmq[0][i]=i;

      for(j=1;(1<<j)<=N;j++)
            for(i=1;i<=N-(1<<j)+1;i++)
                  if(h[rmq[j-1][i]]<=h[rmq[j-1][i+(1<<(j-1))]])
                        rmq[j][i]=rmq[j-1][i];
                  else
                        rmq[j][i]=rmq[j-1][i+(1<<(j-1))];
}

int lca(int i, int j)
{
	int k=0,val=j-i+1,p;

	while(val!=1)
	{
		k++;
		val>>=1;
	}

	if( h[rmq[k][i]] <= h[rmq[k][j-(1<<k)+1]] )
		p=rmq[k][i];
	else p=rmq[k][j-(1<<k)+1];

	return a[p];
}


void write()
{
      int i,x,y,d,l;
      freopen("lca.out","w",stdout);
      for(i=1;i<=K;i++)
      {
            scanf("%d%d",&x,&y);
            x=poz[x]; y=poz[y];
            if(x>y)
            {
                  l=x; x=y; y=l;
            }
            printf("%d\n",lca(x,y));
      }
}

int main()
{
      read();
      euler(1,0);
      RMQ();
      write();
      return 0;
}