Cod sursa(job #617052)

Utilizator blustudioPaul Herman blustudio Data 13 octombrie 2011 20:56:27
Problema Heapuri Scor 0
Compilator cpp Status done
Runda Arhiva educationala Marime 2.94 kb
#include <fstream>
#include <vector>
#include <iostream>
using namespace std;

struct element
{
	int val;
	int ord;
};

int ordine[200001]; //Ordinea cronologica a elementelor
vector<element> heap; //Vectorul ce memoreaza heap-ul
int n; //Numarul de elemente introduse in total in heap

inline int tata(int i)
{
	if (i > 0)
		return (i - 1) / 2;
	else
		return -1;
}
inline int fius(int i)
{
	if ((i * 2 + 1) < heap.size())
		return i * 2 + 1;
	else
		return -1;
}
inline int fiud(int i)
{
	if ((i * 2 + 2) < heap.size())
		return i * 2 + 2;
	else
		return -1;
}
inline void schimba(int a, int b)
{
	element temporar = heap.at(a);
	heap.at(a) = heap.at(b);
	heap.at(b) = temporar;
	ordine[heap.at(a).ord] = a;
	ordine[heap.at(b).ord] = b;
}
inline void inserare(int val)
{
	n++; //Incrementam ordinea cronologica a elementelor
	element e = {val, n}; //Cream elementul adaugat
	heap.push_back(e); //Adaugam elementul in heap
	int poz = heap.size() - 1; //Elementul e pe ultima pozitie
	while ((tata(poz) != -1) && (heap.at(tata(poz)).val < val))
	{
		//Cat timp elementul adaugat este mai mare decat tatal sau
		schimba(poz, tata(poz)); //Schimbam elementul cu tatal sau
		poz = tata(poz); //Pozitia elementului devine cea a tatalui
	}
}
inline int minim()
{
	return heap.at(0).val; //Valoarea minima se afla mereu pe pozitia 0
}
inline void stergere(int i)
{
	heap.at(i) = heap.back(); //Inlocuim elementul de pe pozitia i cu ultimul element
	heap.pop_back(); //Stergem ultimul element
	if (i < heap.size())
	{
		ordine[heap.at(i).ord] = i; //Modificam pozitia in vectorul de ordine
		int max_fiu; //Fiul cu valoarea maxima
		while (((fius(i) != -1) && (heap.at(fius(i)).val > heap.at(i).val)) || ((fiud(i) != -1) && (heap.at(fiud(i)).val > heap.at(i).val)))
		{
			//Cat timp unul dintre fii este mai mare decat valoarea ultimului element
			if ((fius(i) != -1) && (heap.at(fius(i)).val > heap.at(i).val))
				max_fiu = fius(i);
			else if ((fiud(i) != -1) && (fius(i) != -1) && (heap.at(fiud(i)).val > heap.at(fius(i)).val))
				max_fiu = fiud(i);
			schimba(i, max_fiu); //Schimbam i cu maximul dintre fii
			i = max_fiu;
		}
	}
}
int main()
{
	int operatii; //Nr. de operatii
	short int operatia; //Tipul operatiei
	int valoare_operatie;
	ifstream fin("heapuri.in"); //Fisierul de intrare
	ofstream fout("heapuri.out"); //Fisierul de iesire
	fin >> operatii; //Citim nr. de operatii
	while (operatii > 0)
	{
		fin >> operatia;
		switch (operatia)
		{
			case 3:
			{
				fout << minim() << "\n";
				break;
			}
			case 1:
			{
				fin >> valoare_operatie;
				inserare(valoare_operatie);
				break;
			}
			case 2:
			{
				fin >> valoare_operatie;
				cout << operatii << " 3 " << valoare_operatie << " " << ordine[valoare_operatie] << " " << heap.size() << "\n";
				stergere(ordine[valoare_operatie]);
				break;
			}
		}
		operatii--;
	}
	fin.close();
	fout.close();
	return 0;
}