Cod sursa(job #1369431)

Utilizator maritimCristian Lambru maritim Data 3 martie 2015 03:16:25
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 4.62 kb
#include <fstream>
#include <iostream>
#include <vector>

#define father(nod) (nod >> 1)
#define left_son(nod) (nod << 1)
#define right_son(nod) ((nod << 1) + 1)

template <class HeapElement, class Comparator>
class Heap
{
public:
	Heap ();
	~Heap ();
	void Insert (HeapElement element);
	void Remove (int position);
	HeapElement ElementAt (int position);
    int Size();
	void ReplaceAt (int position, HeapElement element);
	HeapElement Top ();

private:
	void Percolate (int position);
	void Sift (int position);
    void Swap (int positionOne, int positionTwo);

private:
	std::vector<int> _heap;
	std::vector<HeapElement> _elements;
	std::vector<int> _elementPositions;
};

template <class HeapElement, class Comparator>
Heap<HeapElement, Comparator>::Heap ()
{
	_heap.push_back (0);
	_elementPositions.push_back (0);
    HeapElement emptyElement;
	_elements.push_back (emptyElement);

}

template <class HeapElement, class Comparator>
void Heap<HeapElement, Comparator>::Insert (HeapElement element)
{
	_elements.push_back (element);

	int position = _elements.size () - 1;

	_heap.push_back (position);
	_elementPositions.push_back (Size ());

	Percolate (Size ());
}

template <class HeapElement, class Comparator>
void Heap<HeapElement, Comparator>::Remove (int position)
{
    int currentPosition = _elementPositions[position];

	Swap (currentPosition, Size ());

	_heap.pop_back ();

	Comparator comparator;
	if (comparator (_elements[_heap[currentPosition]], _elements[_heap[father(currentPosition)]])) {
		Percolate (currentPosition);
		return ;
	}

	Sift (currentPosition);
}

template <class HeapElement, class Comparator>
int Heap<HeapElement, Comparator>::Size (void)
{
	return _heap.size() - 1;
}

template <class HeapElement, class Comparator>
HeapElement Heap<HeapElement, Comparator>::Top (void)
{
/*    std::cout << " da d asd ";
    for (int i=1;i<=Size();i++)
        std::cout << _heap[i] << " ";
    std::cout << "\n";
    for (int i=1;i<_elements.size();i++)
        std::cout << _elements[i] << " ";
    std::cout << "\n"; 

    for (int i=1;i<_elementPositions.size();i++)
        std::cout << _elementPositions[i] << " ";
    std::cout << "\n";*/ 
	return _elements[_heap [1]];
}

template <class HeapElement, class Comparator>
HeapElement Heap<HeapElement, Comparator>::ElementAt (int position)
{
	return _elements [_heap [_elementPositions [position]]];
}

template <class HeapElement, class Comparator>
void Heap<HeapElement, Comparator>::ReplaceAt (int position, HeapElement element)
{
	_elements [_heap [_elementPositions [position]]] = element;
}

template <class HeapElement, class Comparator>
void Heap<HeapElement, Comparator>::Swap (int positionOne, int positionTwo)
{
	_elementPositions[_heap[positionOne]] = positionTwo;
	_elementPositions[_heap[positionTwo]] = positionOne;
	std::swap (_heap[positionOne], _heap[positionTwo]);
}

template <class HeapElement, class Comparator>
void Heap<HeapElement, Comparator>::Percolate (int position)
{
	Comparator comparator;
	while (position > 1) {
		int fatherPosition = father(position);

		if (comparator (_elements[_heap[fatherPosition]], _elements[_heap[position]])) {
			return ;
		}

		Swap (position, fatherPosition);

		position = fatherPosition;
	}
}

template <class HeapElement, class Comparator>
void Heap<HeapElement, Comparator>::Sift (int position)
{
	Comparator comparator;

	while (true) {
        if (left_son (position) > Size ()) {
            return ;
        }

		if (right_son(position) > Size()) {
			if (comparator (_elements[_heap[left_son(position)]], _elements[_heap[position]])) {
				Swap (position, left_son(position));
			}

			return ;
		}

		int bigestSon = comparator (_elements[_heap[left_son(position)]], _elements[_heap[right_son(position)]]) ? 
							left_son(position) : right_son(position);

		if (comparator(_elements[_heap[position]], _elements[_heap[bigestSon]])) {
			return;
		}
	
		Swap (position, bigestSon);
		position = bigestSon;
	}
}

template <class HeapElement, class Comparator>
Heap<HeapElement, Comparator>::~Heap ()
{
	
}

struct comparator {
    int operator() (const int& x, const int& y) {
        if (x <= y)
            return 1;

        return 0;
    }
} ;

int main ()
{
    std::ifstream f("heapuri.in");
    std::ofstream g("heapuri.out");
    Heap<int, comparator> heap;

    int N, stare, a;
    f >> N;
    for (int i=1;i<=N;i++) {
        f >> stare;
        switch (stare) {
            case 1:
                f >> a;
                heap.Insert (a);
                break;
            case 2:
                f >> a;
                heap.Remove (a);
                break;
            case 3:
                g << heap.Top () << "\n";
                break;
        }
    }
}