Cod sursa(job #430911)

Utilizator adrianraduleaRadulea Adrian adrianradulea Data 31 martie 2010 14:24:19
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.4 kb
#include<stdio.h>
FILE *f,*g;
long c[200200],t[3][200500],x,y,z,o,parinte[200200],nr,fin[200500],noduri,i,m,v[3000000],n,nivel[3000000],first[3000000],rmq[30][1000100],put[30],log[3000100],j;
short int viz[100200];
void df(long k,long niv)
{ n++; v[n]=k; nivel[k]=niv; first[k]=n; 
  long p=c[k]; 
  while(p)
   { if(t[1][p]!=parinte[k]){  df(t[1][p],niv+1); n++; v[n]=k; nivel[k]=niv; }
     p=t[2][p];
   }
}
int main()
{ f=fopen("lca.in","r"); g=fopen("lca.out","w");
  fscanf(f,"%ld%ld",&noduri,&m);
  for(i=2;i<=noduri;i++)  { fscanf(f,"%ld",&x); parinte[i]=x; y=x; x=i; if(c[x]==0) { nr++; c[x]=nr; t[1][nr]=y; fin[x]=nr; } else { nr++; t[2][fin[x]]=nr; t[1][nr]=y; fin[x]=nr; }z=x; x=y; y=z; if(c[x]==0) { nr++; c[x]=nr; t[1][nr]=y; fin[x]=nr; } else { nr++; t[2][fin[x]]=nr; t[1][nr]=y; fin[x]=nr; } }
  df(1,1);
  log[1]=0; for(i=2;i<=n;i++) log[i]=log[i/2]+1;
  put[0]=1; for(i=1;i<=20;i++) put[i]=put[i-1]*2;
  for(i=1;i<=n;i++) rmq[0][i]=v[i];
  for(i=1;i<=20;i++)
	for(j=1;j<=n-put[i]+1;j++)
	  if(nivel[rmq[i-1][j]]<=nivel[rmq[i-1][j+put[i-1]]]) rmq[i][j]=rmq[i-1][j];
	  else rmq[i][j]=rmq[i-1][j+put[i-1]];
  for(i=1;i<=m;i++)
   { fscanf(f,"%ld%ld",&x,&y);
     x=first[x]; y=first[y]; if(x>y) { z=x; x=y; y=z; }
	 o=log[y-x+1];
	 if(nivel[rmq[o][x]]<=nivel[rmq[o][y-put[o]+1]]) fprintf(g,"%ld\n",rmq[o][x]); else fprintf(g,"%ld\n",rmq[o][y-put[o]+1]);
   }
  fclose(g);
  return 0;
}