Cod sursa(job #1998611)

Utilizator preda.andreiPreda Andrei preda.andrei Data 8 iulie 2017 15:31:43
Problema Stramosi Scor 20
Compilator cpp Status done
Runda Arhiva de probleme Marime 1.86 kb
#include <cmath>
#include <fstream>
#include <queue>
#include <vector>

using namespace std;

struct Node
{
  vector<int> sons;
  vector<int> ancestors;
};

using Tree = vector<Node>;

inline int log2(int x)
{
  return log(x) / log(2);
}

void Bfs(Tree &t, int node)
{
  queue<pair<int, int>> q;
  q.push({node, 0});

  while (!q.empty()) {
    node = q.front().first;
    int level = q.front().second;
    q.pop();

    if (!t[node].ancestors.empty()) {
      int ancestor = t[node].ancestors[0];
      int order = 0;

      t[node].ancestors.resize(log2(level) + 1);

      while (order < (int)t[ancestor].ancestors.size()) {
        t[node].ancestors[order + 1] = t[ancestor].ancestors[order];
        ancestor = t[node].ancestors.back();
        ++order;
      }
    }

    for (int son : t[node].sons) {
      q.push({son, level + 1});
    }
  }
}

inline int smaller_power(int x)
{
  int power = 25;
  while ((1 << power) > x) {
    --power;
  }
  return power;
}

int FindAncestor(const Tree &t, int node, int order)
{
  int ancestor = node;

  while (order > 0 && ancestor != -1) {
    int power = smaller_power(order);
    if (power >= (int)t[ancestor].ancestors.size()) {
      ancestor = -1;
    } else {
      ancestor = t[ancestor].ancestors[power];
      order -= (1 << power);
    }
  }
  return ancestor;
}

int main()
{
  ifstream fin("stramosi.in");
  ofstream fout("stramosi.out");

  int nodes, q;
  fin >> nodes >> q;

  Tree tree(nodes);
  for (int i = 0; i < nodes; ++i) {
    int father;
    fin >> father;
    if (father != 0) {
      tree[i].ancestors.push_back(father - 1);
      tree[father - 1].sons.push_back(i);
    }
  }

  for (int i = 0; i < nodes; ++i) {
    if (tree[i].ancestors.empty()) {
      Bfs(tree, i);
    }
  }

  while (q--) {
    int node, order;
    fin >> node >> order;
    fout << FindAncestor(tree, node - 1, order) + 1 << "\n";
  }

  return 0;
}