Cod sursa(job #617044)

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

typedef long int key;
typedef long int val;
key ordine[200001];
unsigned long int n;

struct val_t
{
	val v; //Valoarea
	unsigned long int o; //Nr. de ordine cronologica
};

vector<val_t> heap;

inline key tata(key i)
{
	if (i > 0)
		return (i - 1) / 2;
	else
		return -1;
}
inline key fius(key i)
{
	if (i * 2 + 1 < heap.size())
		return i * 2 + 1;
	else
		return -1;
}
inline key fiud(key i)
{
	if (i * 2 + 2 < heap.size())
		return i * 2 + 2;
	else
		return -1;
}
inline void schimba(key a, key b)
{
	val_t t = heap.at(a);
	heap.at(a) = heap.at(b);
	heap.at(b) = t;
	ordine[heap.at(a).o] = a;
	ordine[heap.at(b).o] = b;
}
inline void inserare(val v)
{
	n++; //Incrementam nr. de ordine cronologica
	val_t nod = {v, n}; //Cream nodul cu valoarea v si nr. de ordine
	ordine[n] = heap.size();
	heap.push_back(nod); //Adaugam in heap nodul creat
	key kv = heap.size() - 1; //Calculam indicele
	while ((tata(kv) != -1) && (heap.at(tata(kv)).v > v)) //Cat timp nu am ajuns la radacina si valoarea este mai mare
	{
		schimba(kv, tata(kv)); //Schimba elementul cu tatal sau
		kv = tata(kv); //Schimbam indicii
	}
}
inline void stergere(key kv)
{
	key km;
	heap.at(kv) = heap.at(heap.size() - 1); //Aducem pe pozitia kv ultimul element al heap-ului
	val v = heap.at(kv).v;
	ordine[heap.at(kv).o] = kv;
	heap.pop_back(); //Stergem ultimul element al heap-ului
	while (((fius(kv) > 0) && (v > heap.at(fius(kv)).v)) || ((fiud(kv) > 0) && (v > heap.at(fiud(kv)).v)))
	{
		if (v > heap.at(fius(kv)).v)
			km = fius(kv);
		else
			km = fiud(kv);
		schimba(km, kv); //Schimbam nodurile alese
		kv = km; //Schimbam indicii nodurilor alese
	}
}
inline val minim()
{
	return heap.at(0).v;
}
int main()
{
	unsigned long int operatii; //Nr. de operatii
	unsigned short int operatia; //Tipul operatiei
	val v_op;
	key k_op;
	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;
		cout << operatii << " " << operatia << " ";
		switch (operatia)
		{
			case 3:
			{
				fout << minim() << "\n";
				break;
			}
			case 1:
			{
				fin >> v_op;
				inserare(v_op);
				cout << heap.size();
				break;
			}
			case 2:
			{
				fin >> k_op;
				cout << ordine[k_op] << " " << heap.size();
				stergere(ordine[k_op]);
				break;
			}
		}
		cout << "done\n";
		operatii--;
	}
	fin.close();
	fout.close();
	return 0;
}