Cod sursa(job #2062970)

Utilizator preda.andreiPreda Andrei preda.andrei Data 10 noiembrie 2017 23:12:42
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
#include <fstream>
#include <vector>

#include <iostream>

using namespace std;

class Heap
{
public:
  int GetMin() const { return nodes_[0].value; }

  void Insert(int num);
  void RemoveEntry(int entry);

private:
  struct Node
  {
    int value;
    int entry;

    bool operator<(const Node &other) const
    {
      return value < other.value;
    }
  };

  vector<Node> nodes_;
  vector<int> entry_pos_;

  static constexpr int Father(int pos) { return (pos >> 1); }
  static constexpr int LeftSon(int pos) { return (pos << 1) + 1; }
  static constexpr int RightSon(int pos) { return (pos << 1) + 2; }

  void Swap(int pos1, int pos2);
  void Percolate(int pos);
  void Sift(int pos);
};

void Heap::Swap(int pos1, int pos2)
{
  auto entry1 = nodes_[pos1].entry;
  auto entry2 = nodes_[pos2].entry;

  swap(entry_pos_[entry1], entry_pos_[entry2]);
  swap(nodes_[pos1], nodes_[pos2]);
}

void Heap::Percolate(int pos)
{
  while (pos > 0 && nodes_[pos] < nodes_[Father(pos)]) {
    Swap(pos, Father(pos));
    pos = Father(pos);
  }
}

void Heap::Sift(int pos)
{
  do {
    auto left = LeftSon(pos);
    auto right = RightSon(pos);
    auto son = -1;

    if (right < (int)nodes_.size()) {
      son = (nodes_[left] < nodes_[right] ? left : right);
    } else if (left < (int)nodes_.size()) {
      son = left;
    }

    if (son > -1 && nodes_[son] < nodes_[pos]) {
      Swap(pos, son);
      pos = son;
    } else {
      break;
    }
  } while (pos < (int)nodes_.size());
}

void Heap::Insert(int num)
{
  Node node;
  node.value = num;
  node.entry = entry_pos_.size();

  entry_pos_.push_back(nodes_.size());
  nodes_.push_back(node);

  Percolate(entry_pos_.back());
}

void Heap::RemoveEntry(int entry)
{
  auto pos = entry_pos_[entry];
  Swap(pos, nodes_.size() - 1);

  nodes_.pop_back();
  entry_pos_[entry] = -1;

  if (nodes_.size() > 1) {
    if (pos > 0 && nodes_[pos] < nodes_[Father(pos)]) {
      Percolate(pos);
    } else {
      Sift(pos);
    }
  }
}

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

  int ops;
  fin >> ops;

  Heap heap;

  for (int i = 0; i < ops; ++i) {
    int type, num;
    fin >> type;

    if (type == 3) {
      fout << heap.GetMin() << "\n";
    } else if (type == 1) {
      fin >> num;
      heap.Insert(num);
    } else {
      fin >> num;
      heap.RemoveEntry(num - 1);
    }
  }
  return 0;
}