Cod sursa(job #1759988)

Utilizator andreioneaAndrei Onea andreionea Data 20 septembrie 2016 04:28:12
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.95 kb
#include <fstream>
#include <vector>
#include <algorithm>

struct file_manip {

	std::ifstream fin;
	std::ofstream fout;

	file_manip(const char* filename) {
		std::string infilename  = std::string(filename) + ".in";
		std::string outfilename = std::string(filename) + ".out";
		fin.open(infilename.c_str());
		fout.open(outfilename.c_str());
	}

	template <class T>
	file_manip& operator << (const T& rhs) {
		fout << rhs;
		return *this;
	}
	template <class T>
	file_manip& operator >> (T& rhs) {
		fin >> rhs;
		return *this;
	}
};


class Heap
{
	using ValueAndPos = std::pair<int, int>;
	std::vector<ValueAndPos> heap;
	std::vector<ValueAndPos> vec;

public:

	void Insert(int val)
	{
		heap.push_back({val, vec.size()});
		int pos = heap.size() - 1;
		while (pos > 0)
		{
			const auto parentIdx = (pos - 1) / 2;
			const auto parent = heap[parentIdx].first;
			const auto oldVecIdx = heap[parentIdx].second;
			if (val > parent)
				break;
			std::swap(heap[pos], heap[parentIdx]);
			vec[oldVecIdx].second = pos;
			pos = parentIdx;
		}
		vec.push_back({val, pos});
	}
	int Top() const
	{
		return heap.front().first;
	}
	void Remove(int pos)
	{
		int hpos = vec[pos - 1].second;
		while (hpos < heap.size() - 1)
		{
			auto newHpos = (hpos + 1) * 2 - 1;
			if (newHpos > heap.size() - 1)
			{
				newHpos = heap.size() - 1;
			}
			if (newHpos < heap.size() - 1 && heap[newHpos + 1].first <= heap[newHpos].first)
			{
				heap[hpos] = heap[newHpos + 1];
				vec[heap[hpos].second].second = hpos;
				hpos = newHpos + 1;
			}
			else
			{
				heap[hpos] = heap[newHpos];
				vec[heap[hpos].second].second = hpos;
				hpos = newHpos;	
			}
		}
		heap.pop_back();
	}
};

int main()
{
	file_manip fm("heapuri");
	uint32_t N;
	uint32_t code, val;
	fm >> N;
	Heap h;
	while (N--)
	{
		fm >> code;
		if (code == 3)
		{
			fm << h.Top() << "\n";
		}
		else
		{
			fm >> val;
			if (code == 1)
			{
				h.Insert(val);
			}
			else if (code == 2)
			{
				h.Remove(val);
			}

		}
	}

	return 0;
}