Cod sursa(job #227344)

Utilizator daniel.dumitranDaniel Dumitran daniel.dumitran Data 4 decembrie 2008 10:03:29
Problema Stramosi Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.62 kb
#include <stdio.h>
#include <vector>

#define MAXN 250000

std::vector<int> parents[MAXN + 1];
int n, m;

void calc_parents(int x) {
  std::vector<int>& p = parents[x];
  if (!p[p.size() - 1]) return;
  
  calc_parents(p[0]);
  for (unsigned i = 1;; ++i) {
    std::vector<int>& pp = parents[p[i - 1]];
    if (pp.size() >= i && pp[i - 1])
      p.push_back(pp[i - 1]);
    else
      break;
  }
  p.push_back(0);  
}

int brute_find_parent(int q, int p) {
  for (; p && q; --p)
    q = parents[q][0];
  return q;
}

void check_parents(int x) {
  for (unsigned i = 0; i < parents[x].size(); ++i) {
    int p = parents[x][i];
    if (i == parents[x].size() - 1 && p) {
      printf("bad1\n");
      break;
    }
    if (i < parents[x].size() - 1 && !p) {
      printf("bad2\n");
      break;
    }
    if (brute_find_parent(x, 1 << i) != p) {
      printf("bad3\n");
      break;
    }
  }
}

int find_parent(int q, int p) {
  int rank = parents[q].size();
  
  for (;p && q; --rank) {
    if (rank < 0) return 0;
    if (1 << rank <= p) {
      q = parents[q][rank];
      p -= 1 << rank;
    }
  }

  return q;
}

int main() {
  freopen("stramosi.in", "rt", stdin);
  freopen("stramosi.out", "wt", stdout);

  scanf("%d %d", &n, &m);
  for (int i = 1; i <= n; ++i) {
    int p;
    scanf("%d", &p);
    parents[i].push_back(p);
  }

  for (int i = 1; i <= n; ++i)
    calc_parents(i);

  //  for (int i = 1; i <= n; ++i) check_parents(i);

  for (int i = 0; i < m; ++i) {
    int p, q;
    scanf("%d %d", &q, &p);
    printf("%d\n", find_parent(q, p));

    //    if (find_parent(q, p) != brute_find_parent(q, p))
    //  printf("bad4\n");
  }

  return 0;
}