Cod sursa(job #964123)

Utilizator gabrieligabrieli gabrieli Data 20 iunie 2013 10:38:00
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.33 kb
//BEGIN CUT
#include <algorithm>
#include <cstdlib>
#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
 
typedef int heap_t;

/*
 * Heap implementation which keeps track of the position of elements in the
 * heap and allows updates and removals of elements at any position while
 * maintaining the heap property.
 */
//END CUT
struct Heap
{
	vector<int> heap, pos_heap;
	vector<heap_t> data;

	void init() {
		heap.resize(data.size());
		pos_heap.resize(data.size());

		iota(heap.begin(), heap.end(), 0);
		iota(pos_heap.begin(), pos_heap.end(), 0);

		for (int hpos = parent(heap.size()); hpos >= 0; --hpos)
			down(hpos);
	}

	void swap_h(int hp1, int hp2) {
		swap(heap[hp1], heap[hp2]);
		pos_heap[heap[hp1]] = hp1;
		pos_heap[heap[hp2]] = hp2;
	}

	bool cmp (int hp1, int hp2)
	{ return data[heap[hp1]] <= data[heap[hp2]]; }
	
	int parent (int hpos)
	{ return hpos > 0 ? (hpos-1)/2 : 0; }

	int first_son (int hpos)
	{ return 2 * hpos + 1; }

	int second_son (int hpos)
	{ return 2* hpos + 2; }

	void up (int hpos) {
		for (; hpos != parent(hpos) && !cmp(parent(hpos), hpos); hpos = parent(hpos))
			swap_h(parent(hpos), hpos);
	}

	void down (int hpos) {
		for (int next = hpos; hpos < heap.size(); hpos = next)
		{
        	if (first_son(hpos) < heap.size() && !cmp(next, first_son(hpos)))
        		next = first_son(hpos);
        	if (second_son(hpos) < heap.size() && !cmp(next, second_son(hpos)))
        		next = second_son(hpos);

        	if (hpos == next) break;
        	swap_h(hpos, next);
		}
	}

	void update(int pos) {
		up(pos_heap[pos]);
		down(pos_heap[pos]);
	}

	void remove (int pos) {
		pos = pos_heap[pos];
		swap_h(pos, heap.size()-1);
		heap.pop_back();
		down(pos);
	}

	heap_t top() {
		return data[heap[0]];
	}

	heap_t pop () {
		heap_t t = data[heap[0]];
		remove(0);
		return t;
	}
	
	void push (heap_t x) {
		data.push_back(x);
		heap.push_back(data.size() - 1);
		pos_heap.push_back(heap.size() - 1);
		up(heap.size()-1);
	}
};
//BEGIN CUT
int main()
{
	Heap heap;
	int N, op, x;

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

	for (fin >> N; N; --N)
	{
		fin >> op;
		switch(op) {
			case 1: 
				fin >> x;
				heap.push(x);
				break;
			case 2:
				fin >> x;
				heap.remove(x-1);
				break;
			case 3:
				fout << heap.top() << '\n';
		}
	}

	fin.close();
	fout.close();
	return EXIT_SUCCESS;
}
//END CUT