Cod sursa(job #1050689)

Utilizator rvnzphrvnzph rvnzph Data 8 decembrie 2013 23:06:01
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.23 kb
//Min-Heap
//Simplified
#include <stdio.h>
#include <cstring>	//memset

using namespace std;

#define heapLEN 200001

#define SIZE(v) v[0]
#define VAL(x)	val[heap[x]]

#define ROOT(x) (x>>1)
#define LEFT(x) (x<<1)
#define RIGHT(x) ((x<<1)+1)

int heap[heapLEN];	//min-heap keeps index of value
int val[heapLEN];	//val = array with values in order of insertion
int at[heapLEN];	//at[i] = position of ith inserted element in heap
					//heap[at[i]]=i
					//heap, at = inverse functions

void percolate(int pos)
{
	int aux=heap[pos];

	//!! VAL(aux) is WRONG (val[heap[aux]], where aux=heap[pos])
	for(;pos>1 && VAL(ROOT(pos))>val[aux];pos=ROOT(pos))
	{
		heap[pos]=heap[ROOT(pos)];
		at[heap[pos]]=pos;
	}

	heap[pos]=aux;
	at[aux]=pos;
}

void sift(int pos)
{
	int aux=heap[pos];

	while(LEFT(pos)<=SIZE(heap))
	{
		int next=LEFT(pos);
		if(RIGHT(pos)<=SIZE(heap) && VAL(LEFT(pos))>VAL(RIGHT(pos)))
			next=RIGHT(pos);

		//aux = position
		//val[aux] = value
		//!! VAL(aux) is WRONG (val[heap[aux]], where aux=heap[pos])
		if(val[aux]>VAL(next))
		{
			heap[pos]=heap[next];
			at[heap[pos]]=pos;
		}
		else break;

		pos=next;
	}

	heap[pos]=aux;
	at[heap[pos]]=pos;
}

void insert(int idx)
{
	heap[++SIZE(heap)]=idx;
	at[idx]=SIZE(heap);

	percolate(at[idx]);
}

void cut(int pos)
{
	heap[pos]=heap[SIZE(heap)];
	at[heap[pos]]=pos;

	at[heap[SIZE(heap)]]=0;
	heap[SIZE(heap)--]=0;

	if(pos>SIZE(heap)) return;	//cut made on last element

	if(pos>1&&VAL(ROOT(pos))>VAL(pos)) percolate(pos);
	else sift(pos);
}

void DEBUG()
{
	printf("SIZE(val) = %d\n",SIZE(val));
	printf("SIZE(heap) = %d\n",SIZE(heap));
	printf("val: ");
	for(int i=1;i<=SIZE(val);++i)
		printf("%d ",val[i]);
	printf("\n");
	printf("heap: ");
	for(int i=1;i<=SIZE(heap);++i)
		printf("%d ",heap[i]);
	printf("\n");
	printf("at: ");
	for(int i=1;i<=SIZE(val);++i)
		printf("%d ",at[i]);
	printf("\n\n");
}

int main()
{
	freopen("heapuri.in","r",stdin);
	freopen("heapuri.out","w",stdout);

	int N;
	scanf("%d",&N);

	while(N--)
	{
		int cod;
		scanf("%d",&cod);

		switch(cod)
		{
			case 1:
				scanf("%d",&val[++SIZE(val)]);
				insert(SIZE(val));
				break;
			case 2:
				int i;
				scanf("%d",&i);
				cut(at[i]);
				break;
			case 3:
				printf("%d\n",val[heap[1]]);
				break;
		}
	}

	return 0;
}