Cod sursa(job #936806)

Utilizator toranagahVlad Badelita toranagah Data 8 aprilie 2013 20:51:44
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.51 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <vector>
using namespace std;

ifstream fin("heapuri.in");
ofstream fout("heapuri.out");
const int MAX_N = 200100;

class Heap {
public:
  Heap();
  int size();
  bool empty();
  void push(const int &x);
  void pop();
  void clear();
  int top();
private:
  vector<int> _h;
  void sift(int node);
  void percolate(int node);
  void erase(int node);
  int left_son(int node);
  int right_son(int node);
  int father(int node);
  friend void remove_element(int n);
};

Heap heap;
int pos[MAX_N];
int order[MAX_N];
int pos_size = 0;
int order_size = 0;

void remove_element(int n) {
  heap.erase(pos[n]);
}

int main() {
  int N;
  fin >> N;
  for (int i = 1, cod, x; i <= N; ++i) {
    fin >> cod;
    if (cod < 3) fin >> x;

    switch (cod) {
    case 1:
      heap.push(x);
      break;
    case 2:
      remove_element(x);
      break;
    case 3:
      fout << heap.top() << '\n';
      break;
    default:
      cerr << "INVALID INPUT" << endl;
    }
  }

  return 0;
}


Heap::Heap() {
  _h.push_back(0);
}

inline bool Heap::empty() {
  return (size() == 0);
}

inline int Heap::size() {
  return _h.size() - 1;
}

inline void Heap::push(const int &x) {
  _h.push_back(x);
  pos[++pos_size] = size();
  order[size()] = pos_size;
  percolate(size());
}

inline void Heap::pop() {
  swap(pos[order[size()]], pos[order[1]]);
  swap(order[size()], order[1]);s
  swap(_h[1], _h.back());
  _h.pop_back();
  sift(1);
}

inline int Heap::top() {
  return _h[1];
}

inline void Heap::clear() {
  _h.resize(1);
}

void Heap::erase(int node) {
  swap(pos[order[size()]], pos[order[node]]);
  swap(order[size()], order[node]);
  swap(_h[size()], _h[node]);
  _h.pop_back();

  sift(node);
  percolate(node);
}

void Heap::sift(int node) {
  if (left_son(node) > size()) return;

  int l = left_son(node);
  int r = right_son(node);
  
  int best = l;
  if (r <= int(size()) && _h[r] < _h[l]) {
    best = r;
  }

  if (_h[best] < _h[node]) {
    swap(pos[order[best]], pos[order[node]]);
    swap(order[best], order[node]);

    swap(_h[best], _h[node]);
    sift(best);
  }
}

void Heap::percolate(int node) {
  if (father(node) == 0) return;

  int f = father(node);

  if (_h[node] < _h[f]) {
    swap(pos[order[f]], pos[order[node]]);
    swap(order[f], order[node]);

    swap(_h[node], _h[f]);
    percolate(f);
  }
}

inline int Heap::left_son(int node) {
  return node * 2;
}

inline int Heap::right_son(int node) {
  return node * 2 + 1;
}

inline int Heap::father(int node) {
  return node / 2;
}