Cod sursa(job #363608)

Utilizator andrei.sfrentSfrent Andrei andrei.sfrent Data 13 noiembrie 2009 21:08:39
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 1.89 kb
#include <cstdio>

#define AFIS_ELEM_MINIM 3
#define INSERARE 1
#define STERGERE 2

#define MAX_HEAP 200010
#define MAX_OPERATII 200010

struct NOD
{
	int valoare, ord; //valoare si numarul care indica al catelea e intrat in multime
};

NOD h[MAX_HEAP];
int p[MAX_OPERATII];
int nr_elem = 0, dim_heap = 0;

inline void scrie_minim() {	printf("%d\n", h[1].valoare); }

inline void interschimb(NOD &a, NOD &b)
{
	NOD aux = a;
	a = b;
	b = aux;
}

inline void interschimb(int &a, int &b)
{
	int aux = a;
	a = b;
	b = aux;
}

void urca_in_heap(int poz)
{
	if(poz == 1) return;
	if(h[poz].valoare < h[poz/2].valoare)
	{
		interschimb(h[poz], h[poz/2]);
		p[h[poz].ord] = poz;
		p[h[poz/2].ord] = poz/2;
		urca_in_heap(poz/2);
	}
}

void insereaza(int x)
{
	++nr_elem;
	++dim_heap;
	
	h[dim_heap].valoare = x;
	h[dim_heap].ord = nr_elem;
	p[nr_elem] = dim_heap;
	
	urca_in_heap(dim_heap);
}

void coboara_in_heap(int poz)
{
	int poz_min = poz;
	if(h[poz_min].valoare > h[poz*2].valoare) poz_min = 2*poz;
	if(h[poz_min].valoare > h[poz*2+1].valoare) poz_min = 2*poz+1;
	
	if(h[poz].valoare > h[poz_min].valoare && poz_min <= dim_heap)
	{
		interschimb(h[poz], h[poz_min]);
		p[h[poz].ord] = poz;
		p[h[poz_min].ord] = poz_min;
		coboara_in_heap(poz_min);
		return;
	}
}

void sterge(int x)
{
	int o1, o2;
	
	o1 = h[p[x]].ord;
	o2 = h[dim_heap].ord;
	
	interschimb(h[p[x]], h[dim_heap]);
	interschimb(p[o1], p[o2]);
	dim_heap--;
	coboara_in_heap(p[o2]);
}

int main()
{
	freopen("heapuri.in", "r", stdin);
	freopen("heapuri.out", "w", stdout);
	int numar_operatii, op_crt, operatie, valoare;
	scanf("%d", &numar_operatii);
	for(op_crt=0;op_crt<numar_operatii;++op_crt)
	{
		scanf("%d", &operatie);
		if(operatie == INSERARE)
		{
			scanf("%d", &valoare);
			insereaza(valoare);
		}
		if(operatie == STERGERE)
		{
			scanf("%d", &valoare);
			sterge(valoare);
		}
		if(operatie == AFIS_ELEM_MINIM) scrie_minim();
	}
	fclose(stdout);
	return 0;
}