Cod sursa(job #2438957)

Utilizator andra1782Andra Alazaroaie andra1782 Data 14 iulie 2019 14:35:31
Problema Lowest Common Ancestor Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.3 kb
#include <stdio.h>
#define MAXN 100000
#define MAXH 18
FILE *fin,*fout;
int n,v[MAXN+1],next[MAXN+1];
int k,fap[MAXN+1],h[MAXN+1],e[2*MAXN-1][MAXH],log2[2*MAXN-1],p2[2*MAXN-1];

void dfs(int nod, int ha){
  if(!fap[nod]){
    fap[nod]=k;
    h[nod]=ha;
  }
  e[k++][0]=nod;
  int i=v[nod];
  while(i){
    dfs(i,ha+1);
    e[k++][0]=nod;
    i=next[i];
  }
}

void rmq(){
  for(int p=1,a=1; p<MAXH; p++,a<<=1)
    for(int i=0; i<=k-2*a; i++){
      e[i][p]=e[i][p-1];
      if(h[e[i][p]]>h[e[i+a][p-1]])
        e[i][p]=e[i+a][p-1];
    }
}

void log(){
  p2[1]=1;
  for(int i=2; i<k; i++){
    log2[i]=log2[i/2]+1;
    p2[i]=p2[i/2]*2;
  }
}

int lca(int x, int y){
  if(x==y)
    return e[x][0];
  if(x>y){
    int aux=x;
    x=y;
    y=aux;
  }
  int l=log2[y-x+1],p=p2[y-x+1];
  if(h[e[x][l]]<h[e[y-p+1][l]])
    return e[x][l];
  return e[y-p+1][l];
}

int main(){
  fin=fopen("lca.in","r");
  fout=fopen("lca.out","w");
  int m,i,parinte,x,y;

  fscanf(fin,"%d%d",&n,&m);
  for(i=2; i<=n; i++){
    fscanf(fin,"%d",&parinte);
    next[i]=v[parinte];
    v[parinte]=i;
  }
  dfs(1,0);
  rmq();
  log();
  for(i=0; i<m; i++){
    fscanf(fin,"%d%d",&x,&y);
    fprintf(fout,"%d\n",lca(fap[x],fap[y]));
  }
  fclose(fin);
  fclose(fout);
  return 0;
}