Cod sursa(job #1201324)

Utilizator hrazvanHarsan Razvan hrazvan Data 24 iunie 2014 21:29:40
Problema Lowest Common Ancestor Scor 10
Compilator c Status done
Runda Arhiva educationala Marime 1.56 kb
#include <stdio.h>
#define MAXN 100000
#define LG_MAXN 16

int ult[MAXN], next[MAXN];
int euler[2 * MAXN], apar[MAXN], dr = 0;
int rmq[LG_MAXN + 1][2 * MAXN], lg[2 * MAXN + 1];

int min2(int a, int b)
{return a < b ? a : b;}

void creezeuler(int x){
  if(apar[x] == 0)  apar[x] = dr;
  int poz = ult[x];
  euler[dr] = x;
  dr++;
  while(poz > 0){
    creezeuler(poz);
    euler[dr] = x;
    dr++;
    poz = next[poz];
  }
  return ;
}

void creezlg(int n){
  int i/*, k = 0*/;
  //lg[1] = k;
  lg[1] = 0;
  for(i = 2; i <= n; i++){
    lg[i] = lg[i / 2] + 1;
    //lg[i] = k;
    //if(lg[(i >> 1) + 1] + 1 > k) k++;
  }
  return ;
}

void creezrmq(){
  int i, j;
  for(i = 0; i < dr; i++) rmq[0][i] = euler[i];
  for(i = 1; i <= lg[dr]; i++){
    for(j = 0; j < dr; j++){
      if(j >= 1 << (i - 1)){
        rmq[i][j] = min2(rmq[i - 1][j - (1 << (i - 1))], rmq[i - 1][j]);
      }
    }
  }
  return ;
}

int main(){
  FILE *in = fopen("lca.in", "r");
  int n, m;
  fscanf(in, "%d%d", &n, &m);
  int i, x;
  for(i = 1; i < n; i++){
    fscanf(in, "%d", &x);
    x--;
    next[i] = ult[x];
    ult[x] = i;
  }
  creezeuler(0);
  creezlg(2 * n);
  creezrmq();
  FILE *out = fopen("lca.out", "w");
  int l, a, b, aux;
  for(i = 0; i < m; i++){
    fscanf(in, "%d%d", &a, &b);
    a--;  b--;
    if(apar[a] > apar[b]){
      aux = a;  a = b;  b = aux;
    }
    l = lg[apar[b] - apar[a] + 1];
    fprintf(out, "%d\n", min2(rmq[l][apar[a] + (1 << l)], rmq[l][apar[b]]) + 1);
  }
  fclose(in);
  fclose(out);
  return 0;
}