Cod sursa(job #3216340)

Utilizator Remus.RughinisRemus Rughinis Remus.Rughinis Data 15 martie 2024 22:18:59
Problema Lowest Common Ancestor Scor 60
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 1.67 kb
#include <iostream>
#include <fstream>
#define MAXN 100000
#define LOGN 17
#define DEBUG 0

using namespace std;

FILE *fout, *fin; 
int d[MAXN][LOGN], niv[MAXN];

int getNiv(int id){
  if(niv[id] != -1)
    return niv[id];

  niv[id] = getNiv(d[id][0]) + 1;
  return niv[id];
}

void stramosi(){
  int n, q;
  fscanf(fin, "%d%d", &n, &q);
  for(int i = 1; i < n; i ++){
    fscanf(fin, "%d", &d[i][0]);
    d[i][0] --;
  }
  for(int j = 1; (1 << j) < n; j ++){
    for(int i = 1; i < n; i ++){
      d[i][j] = d[ d[i][j - 1] ][j - 1];
    }
  }

  for(int i = 0; i < n; i ++){
    niv[i] = -1;
  }
  niv[0] = 0;
  for(int i = 0; i < n; i ++){
    getNiv(i);
  }

  if(DEBUG){
    printf("Nivel: ");
    for(int i = 0; i < n; i ++){
      printf("%d ", getNiv(i));
    }
    printf("\n\n");
    for(int i = 0; i < n; i ++){
      for(int j = 0; (1 << j) < n; j ++)
        printf("%d ", d[i][j]);
      printf("\n");
    }
  }

  fflush(NULL);
  int logn = 0;
  while((1 << (logn+1)) < n)
    logn ++;


  for(int i = 0; i < q; i ++){
    int x, y;
    fscanf(fin, "%d%d", &x, &y);
    x --;
    y --;

    // Aduc nodurile la acelasi nivel
    while(getNiv(x) > getNiv(y))
      x = d[x][0];
    while(getNiv(x) < getNiv(y))
      y = d[y][0];

    int j = logn;

    if(x == y)
      fprintf(fout, "%d\n", x + 1);
    else{
      // Caut stramosul comun
      while(d[x][0] != d[y][0]){
        fflush(NULL);
        if(d[x][j] != d[y][j]){
          x = d[x][j];
          y = d[y][j];
        }
        j --;
      }

      fprintf(fout, "%d\n", d[x][0] + 1);
    }
  }
}

int main(){
  fin = fopen("lca.in", "r");
  fout = fopen("lca.out", "w");

  stramosi();

  fclose(fin);
  fclose(fout);
  return 0;
}