Cod sursa(job #648560)

Utilizator vlad.maneaVlad Manea vlad.manea Data 13 decembrie 2011 18:23:48
Problema Heapuri Scor 100
Compilator c Status done
Runda Arhiva educationala Marime 2.82 kb
#include <stdio.h>
#include <limits.h>
#define NMax 200000

int count, size;

int HeapValue[NMax], HeapAdded[NMax], HeapCount[NMax];

void swap(int * a, int * b)
{
	int aux = *a;
	*a = *b;
	*b = aux;
}

void interchange(int index, int half)
{
	swap(&HeapValue[index], &HeapValue[half]);
	swap(&HeapAdded[index], &HeapAdded[half]);
	swap(&HeapCount[HeapAdded[index]], &HeapCount[HeapAdded[half]]);
}

void moveUpwards(int position)
{
	int index, half;
	
	// move from position to the top
	for (index = position; index > 0; index = half)
	{
		half = (index - 1) >> 1;
		
		if (HeapValue[half] > HeapValue[index])
		{
			// change parent with element
			interchange(index, half);
		}
		else
		{
			break;
		}
	}	
}

void moveDownwards(int position)
{
	int minValue, minSon, leftSon, rightSon;
	
	// start from the position downwards
	while(1)
	{
		minValue = HeapValue[position];
		minSon = INT_MAX;
		leftSon = (position << 1) | 1;
		rightSon = (position + 1) << 1;
		
		// test the left son
		if (leftSon < size && minValue > HeapValue[leftSon])
		{
			minSon = leftSon;
			minValue = HeapValue[leftSon];
		}
		
		// test the right son
		if (rightSon < size && minValue > HeapValue[rightSon])
		{
			minSon = rightSon;
			minValue = HeapValue[rightSon];
		}
		
		// is a change imposed?
		if (minValue < HeapValue[position])
		{
			interchange(position, minSon);
			position = minSon;
		}
		else
		{
			break;
		}
	}
}

void insertToHeap(int value)
{
	// heapValue retains the value of node in heap
	HeapValue[size] = value;
	
	// heapAdded[i] retains when was that node in heap added
	HeapAdded[size] = count;

	// heapCount[i] retains the heap node index that was ith added
	HeapCount[count] = size;
	
	// move upwards
	moveUpwards(size);
	
	++count;
	++size;
}

void removeFromHeap(int index)
{
	interchange(index, size - 1);
	int value = HeapValue[size - 1];
	--size;
	
	// is the heap node smaller?
	if(HeapValue[index] < value)
	{
		// move it to the top
		moveUpwards(index);
	}
	
	// is the heap node larger?
	else if (HeapValue[index] > value)
	{
		// move it to the bottom
		moveDownwards(index);
	}
}

int getMinFromHeap()
{
	// get it in constant time
	return HeapValue[0];
}

int main()
{
	int operations, operation, value;
	freopen("heapuri.in", "r", stdin);
	freopen("heapuri.out", "w", stdout);
	scanf("%d", &operations);
	
	while (operations--)
	{
		scanf("%d", &operation);
		
		switch(operation)
		{
		// insert case
		case 1:
			
			scanf("%d", &value);
			insertToHeap(value);
			break;

		// remove case
		case 2:
			
			scanf("%d", &value);
			removeFromHeap(HeapCount[value - 1]);
			break;

		// get minimum case
		case 3:
			
			printf("%d\n", getMinFromHeap());
			break;
		}
	}
	
	return 0;
}