Cod sursa(job #1572292)

Utilizator stoianmihailStoian Mihail stoianmihail Data 18 ianuarie 2016 20:40:18
Problema Stramosi Scor 100
Compilator c Status done
Runda Arhiva de probleme Marime 1.67 kb
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <ctype.h>

#define Nadejde 250000
#define Dragoste 4096
#define MAX_LOG 18

typedef struct {
  int v, next;
} list;

int N, Q, lim;
int lg[(1 << MAX_LOG) + 1];           // lg[i] este log2(i).
int father[MAX_LOG + 1][Nadejde + 1]; // father[i][u] este al 2 ^ i - lea tata al nodului "u".

int pos = Dragoste;
char c, buff[Dragoste];

/** Ia urmatorul caracter din fisier. **/
char getChar(FILE *f) {
  if (pos == Dragoste) {
    fread(buff, 1, Dragoste, f);
    pos = 0;
  }
  return buff[pos++];
}

/** Citeste urmatorul numar din fisier. **/
void freef(FILE *f, const char *arg, int *result) {
  *result = 0;
  do {
    c = getChar(f);
  } while (!isdigit(c));
  do {
    *result = (*result << 3) + (*result << 1) + c - '0';
    c = getChar(f);
  } while (isdigit(c));
}

/** Precalculeaza "lg". **/
void log() {
  int i;

  for (i = 0; i <= MAX_LOG; i++) {
    lg[1 << i] = i;
  }
}

int main(void) {
  int u, i, k;
  FILE *f = fopen("stramosi.in", "r");

  /* Citirea datelor. */
  freef(f, "%d", &N);
  freef(f, "%d", &Q);
  for (lim = N + 1, u = 1; u <= N; u++) {
    freef(f, "%d", &father[0][u]);
  }

  /* Calcularea solutiei. */
  log();

  /* Precalcularea parintilor. */
  for (i = 1; i <= MAX_LOG; i++) {
    for (u = 1; u <= N; u++) {
      father[i][u] = father[i - 1][father[i - 1][u]];
    }
  }

  /* Raspunde la intrebari. */
  freopen("stramosi.out", "w", stdout);
  while (Q--) {
    freef(f, "%d", &u);
    freef(f, "%d", &k);

    for (; k; k &= k - 1) {
      u = father[lg[k & -k]][u];
    }
    fprintf(stdout, "%d\n", u);
  }
  fclose(f);
  fclose(stdout);

  /// Multumim Doamne!
  puts("Doamne ajuta!");
  return 0;
}