Cod sursa(job #245705)

Utilizator P1gl3TGilca Mircea Alexandru P1gl3T Data 18 ianuarie 2009 17:56:53
Problema Heapuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 2.35 kb
#include<stdio.h>
#define N 100000
int heap[N],poz[N],ord[N],n=0,aux,ok;
// poz[i] pozitia in heap a celui de-al i-lea nod intrat in heap
// ord[i] al catelea intrat in heap e nodul i

inline int left_son(int x){
	return 2*x;
}
inline int right_son(int x){
	return 2*x+1;
}
inline int parent(int x){
	return x/2;
}

inline void replace(int p, int q)
{
	if(heap[p]==heap[q]) return;
	ok=0;
	aux=heap[p];
	heap[p]=heap[q];
	heap[q]=aux;
	aux=poz[ord[p]];
	poz[ord[p]]=poz[ord[q]];
	poz[ord[q]]=aux;
	aux=ord[p];
	ord[p]=ord[q];
	ord[q]=aux;
}

inline void up(int x)
{
	ok=0;
	while(x&&(!ok))
	{
		ok=1;
		if(right_son(x)<=n) // nodul curent are ambii fii
		{
			if(heap[x]>heap[left_son(x)]||heap[x]>heap[right_son(x)]) //nodul curent e mai mare decat unul dintre fii
				if(heap[left_son(x)]<heap[right_son(x)])
					replace(x,left_son(x)); //interschimb
				else
					replace(x,right_son(x)); //interschimb
		}
		
		else //nodul curet are doar fiul stang
			if(heap[x]>heap[left_son(x)])
				replace(x,left_son(x)); //interschimb
			
		x=parent(x); //urc la urmatorul nivel
	}
}

inline void down(int x)
{
	
	int son; //fiul care trebuie sa urce
	do
	{
		if(left_son(x)>n) return;
		son=0;
		ok=1;
		if(right_son(x)<=n) //daca nodul curent are ambii fii
		{
			if(heap[left_son(x)]<heap[x]||heap[right_son(x)]<heap[x]) //nodul curent are un fiu mai mic decat el
				if(heap[left_son(x)]<heap[right_son(x)])
					son=left_son(x);
				else
					son=right_son(x);
		}
		else //nodul curent are doar nodul stang
			if(heap[x]>heap[left_son(x)])
				son=left_son(x);
		replace(x,son);
		if(ok) son=0;
		else x=son;
	}while(son);
}

inline void insert(int x)
{
	heap[++n]=x;
	poz[n]=n;
	ord[n]=n;
	up(parent(n));
}

inline void remove(int x)
{
	//inlocuiesc nodul x cu ultimul nod si scad numarul nodurilor
	heap[x]=heap[n];
	poz[ord[n]]=x;
	ord[x]=ord[n];
	--n;
	
	up(parent(x)); //ori o sa il urce ori o sa il coboare
	down(x);
}
int main()
{
	freopen("heapuri.in","r",stdin);
	freopen("heapuri.out","w",stdout);
	int nr,op,x;
	scanf("%d",&nr);
	for(;nr>0;--nr)
	{
		scanf("%d",&op);
		if(op==3) printf("%d\n",heap[1]); //afisez minimul
		else
		{
			scanf("%d",&x);
			if(op==1) //inserez elementul x
				insert(x);
			else //sterg al x-lea nod intrat
				remove(poz[x]);
		}
	}
	return 0;
}