Cod sursa(job #431545)

Utilizator bogdanhm999Casu-Pop Bogdan bogdanhm999 Data 1 aprilie 2010 09:48:14
Problema Lowest Common Ancestor Scor 70
Compilator cpp Status done
Runda Arhiva educationala Marime 1.57 kb
//LOWEST COMMON ACESTOR

#include <stdio.h>
#include <bitset>
#define N 100500

using namespace std;
int n,m,q,a,b,i,j,bq,nivel=0,L,sz;
int x[N],g[N],poz[2*N],lg[2*N],r[20][2*N],E[2*N],NIV[2*N];
bitset <N> mark;
int * v[N];
int t[4000005];

inline int pmin(int x,int y){
  if ( NIV[x] <= NIV[y] )return x;
  else return y;
}

inline int RMQ(int x,int y){
  int D=y-x+1;  
  return pmin( r[ lg[D] ] [x], r[ lg[D] ] [ y -( 1 << lg[D] ) + 1 ] );
}

void DFS(int x){
  int i,fiu;
  mark[x]=1;
  ++nivel;
  E[++q]=x; NIV[q] = nivel;
  for (i=0;i<g[x];++i){
    fiu=v[x][i];
    if (!mark[fiu]){DFS(fiu); E[++q]=x; NIV[q] = nivel; }
  }
  nivel--;
}

int main(){
  freopen("lca.in","r",stdin);
  freopen("lca.out","w",stdout);
  
  scanf("%d %d",&n,&m);
  for (i=1;i<n;++i){scanf("%d",&x[i]); g[x[i]]++;g[i+1]++;}
  for (i=1;i<=n;++i){v[i]=(int*)malloc(sizeof(int)*(g[i]+1));g[i]=0;}
  for (i=1;i<n;++i){v[x[i]][g[x[i]]++]=i+1;v[i+1][g[i+1]++]=x[i];}
  //parcurgerea Euler
  DFS(1);
  for (i=1;i<=q;++i) if ( !poz[ E[i] ] ) poz[E[i]]=i;
  
  //preproc
  for (i=1;i<=q;++i) r[0][i]=i;   //initializare pt 2^0
  for (i=2;i<=q;++i) lg[i] = lg[i>>1]+1;//vector de logaritmi
  L = lg[q];

  for (i=1;i<=L;++i,sz>>=1){
    sz=q-(1<<i)+1;
    for (j=1;j<=sz;j++)
            r[i][j] = pmin( r[i-1][j], r[i-1][j+(1<<(i-1))] );
  }
  //query
  for (i=0;i<m;++i)scanf("%d %d\n",&t[i<<1],&t[(i<<1)+1]);
  for (i=0; i<m; i++){
    a=t[i<<1];b=t[(i<<1)+1];
    if (poz[a]>poz[b]){j=a;a=b;b=j;}
    printf("%d\n", E[ RMQ(poz[a], poz[b]) ]);
  }
  
return 0;
}