Cod sursa(job #191714)

Utilizator cata00Catalin Francu cata00 Data 28 mai 2008 03:18:40
Problema Stramosi Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.64 kb
#include <stdio.h>
#include <stdlib.h>

typedef unsigned char byte;

typedef struct list {
  int node;
  byte level;
  list *next;
};

FILE *fin, *fout;
int n, numTests;
// a[n][k] = the node 2^k levels above n.
int a[250010][20];
list *unknown;

void read() {
  fscanf(fin, "%d %d", &n, &numTests);
  for (int i = 1; i <= n; i++) {
    fscanf(fin, "%d", &a[i][0]);
    for (int j = 1; j < 20; j++) {
      a[i][j] = -1;
    }
  }
  unknown = NULL;
}

inline void enqueue(int node, int level) {
  list *l = (list*) malloc(sizeof(list));
  l->node = node;
  l->level = level;
  l->next = unknown;
  unknown = l;
}

inline void dequeue() {
  list *tmp = unknown;
  unknown = unknown->next;
  free(tmp);
}

void lazyEval(int node, int level) {
  if (a[node][level] != -1) {
    return;
  }

  enqueue(node, level);
  while (unknown) {
    int halfway = a[unknown->node][unknown->level - 1];
    if (halfway == -1) {
      enqueue(unknown->node, unknown->level -1);
    } else {
      int top = a[halfway][unknown->level - 1];
      if (top == -1) {
	enqueue(halfway, unknown->level -1);
      } else {
	a[unknown->node][unknown->level] = top;
	dequeue();
      }
    }
  }
}

int query(int node, int level) {
  int log = 0;
  while (level && node) {
    if (level % 2) {
      lazyEval(node, log);
      node = a[node][log];
    }
    log++;
    level >>= 1;
  }
  return node;
}

int main() {
  fin = fopen("stramosi.in", "rt");
  fout = fopen("stramosi.out", "wt");
  read();

  for (int test = 0; test < numTests; test++) {
    int node, level;
    fscanf(fin, "%d %d", &node, &level);
    fprintf(fout, "%d\n", query(node, level));
  }

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