Cod sursa(job #418723)

Utilizator mihaionlyMihai Jiplea mihaionly Data 16 martie 2010 12:11:05
Problema Lowest Common Ancestor Scor 30
Compilator cpp Status done
Runda Arhiva educationala Marime 1.45 kb
#include <cstdio>
using namespace std;
#define nmax 100002
FILE *f=fopen("lca.in","r");
FILE *g=fopen("lca.out","w");
int n,m;
int RMQ[20][4*nmax],log[nmax];
int p[nmax];
bool viz[nmax];
int Eu[4*nmax],k,lv[4*nmax];
struct graf
 {
 graf *urm;
 int x;
 } *G[nmax];
void add(graf *&g,int x)
 {
 graf *p=new graf;
 p->x=x;
 p->urm=g;
 g=p;
 }
inline int min(int x,int y)
 {
 if(x<y) return x;
 return y;
 }
inline int max(int x,int y)
 {
 if(x>y) return x;
 return y;
 }
void dfs(int x,int l)
 {
 viz[x]=true;
 Eu[++k]=x;
 lv[k]=l;
 //RMQ[0][k]=k;
 if(!p[x])
  p[x]=k;
 for(graf *p=G[x];p!=NULL;p=p->urm)
  {
  if(!viz[p->x])
   {
   dfs(p->x,l+1);
   Eu[++k]=x;
   lv[k]=l;
   }
  }
 }
void rmq()
 {
 int i,j;
 for(i=2;i<=k;i++) {log[i]=log[i/2]+1;RMQ[0][i]=i;}
 RMQ[0][1]=1;
 for(i=1;(1<<i)<=k;i++)
  for(j=1;j+(1<<i)-1<=k;j++)
   {
   if(lv[RMQ[i-1][j]]<lv[RMQ[i-1][j+(1<<(i-1))]])
    RMQ[i][j]=RMQ[i-1][j];
   else
    RMQ[i][j]=RMQ[i-1][j+(1<<(i-1))];
   }
 }
int query(int x,int y)
 {
 int l,d;
 d=y-x+1;
 l=log[d];
 if(lv[RMQ[l][x]]<lv[RMQ[l][x+(d-(1<<l))]])
  return Eu[RMQ[l][x]];
 else 
  return Eu[RMQ[l][x+(d-(1<<l))]];
 } 
int main()
 {
 int i,x,y;
 fscanf(f,"%d %d",&n,&m);
 for(i=2;i<=n;i++)
  {
  fscanf(f,"%d",&x);
  add(G[x],i);
  }
 dfs(1,0);
 rmq();
 for(i=1;i<=m;i++)
  {
  fscanf(f,"%d %d",&x,&y);
  fprintf(g,"%d\n",query(min(p[x],p[y]),max(p[x],p[y])));
  }
 return 0;
 }