Cod sursa(job #1998631)

Utilizator preda.andreiPreda Andrei preda.andrei Data 8 iulie 2017 16:52:00
Problema Stramosi Scor 90
Compilator c Status done
Runda Arhiva de probleme Marime 1.8 kb
#include <stdio.h>
#include <stdlib.h>

#define MAXN 250000
#define MAXANC 30

typedef struct ListNode_s
{
  int value;
  struct ListNode_s *next;
} ListNode;

typedef struct List_s
{
  ListNode *begin, *end;
} List;

int ancestors[MAXANC][MAXN + 1];
List sons[MAXN + 1];

void AddToList(List *l, int v)
{
  ListNode *n = (ListNode*)malloc(sizeof(ListNode));
  n->value = v;
  n->next = NULL;

  if (l->begin == NULL) {
    l->begin = l->end = n;
  } else {
    l->end->next = n;
    l->end = n;
  }
}

void RemoveFromList(List *l)
{
  ListNode *tr = l->begin;
  l->begin = tr->next;
  free(tr);
  if (l->begin == NULL) {
    l->end = NULL;
  }
}

void Bfs(int n)
{
  List q = (List){NULL, NULL};
  ListNode *it;
  int o, a;

  AddToList(&q, n);

  while (q.begin) {
    n = q.begin->value;
    RemoveFromList(&q);

    if (ancestors[0][n] > 0) {
      o = 1;
      a = ancestors[0][n];
      while (ancestors[o - 1][a] > 0) {
        ancestors[o][n] = ancestors[o - 1][a];
        a = ancestors[o][n];
        ++o;
      }
    }

    it = sons[n].begin;
    while (it) {
      AddToList(&q, it->value);
      it = it->next;
    }
  }
}

int power(int n)
{
  int p = MAXANC - 1;
  while ((1 << p) > n) {
    --p;
  }
  return p;
}

int Res(int n, int f)
{
  int p;
  while (f > 0 && n > 0) {
    p = power(f);
    n = ancestors[p][n];
    f -= (1 << p);
  }
  return n;
}

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

  int n, m, i, f;
  ListNode *it;

  fscanf(fin, "%d%d", &n, &m);

  for (i = 1; i <= n; ++i) {
    fscanf(fin, "%d", &f);
    ancestors[0][i] = f;
    AddToList(&sons[f] , i);
  }

  it = sons[0].begin;
  while (it) {
    Bfs(it->value);
    it = it->next;
  }

  while (m--) {
    fscanf(fin, "%d%d", &n, &f);
    fprintf(fout, "%d\n", Res(n, f));
  }

  return 0;
}