Cod sursa(job #1479533)

Utilizator alexandru.huleaAlexandru Hulea alexandru.hulea Data 31 august 2015 16:07:12
Problema Heapuri Scor 20
Compilator cpp Status done
Runda Arhiva educationala Marime 3.95 kb
//#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#define MAX 200100

using namespace std;

int nr = 0;
int heapNr = 0;
// i - ordinea temporala de intrare in vector
// vec[i] - valoarea introdusa la timpul i
// heap[i] - valoarea timpului valorii - ordonare dupa vec[i]
// pos[i] - pozitia in cadrul heapului a valorii temporale
int vec[MAX], heap[MAX], pos[MAX];

// 2 * i + 1 si 2 * i + 2 vor fi copiii valorii i

void upheap(int heapPosition) {

	int me = heapPosition;
	int dad = (me - 1) >> 1;

	while (me != 0) {
		if (vec[heap[me]] < vec[heap[dad]]) {
			pos[heap[me]] = dad;
			pos[heap[dad]] = me;

			int aux = heap[me];
			heap[me] = heap[dad];
			heap[dad] = aux;

			me = dad;
			dad = (me - 1) >> 1;
		}
		else {
			break;
		}
	}
}

void downHeap(int heapPosition) {

	int child1 = (heapPosition << 1) + 1;
	int child2 = (heapPosition << 1) + 2;

	while (true) {
		// daca nu exista niciun copil break;
		if (child1 >= heapNr) {
			break;
		}

		// daca exista doar un copil
		if (child2 == heapNr) {
			if (vec[heap[heapPosition]] < vec[heap[child1]]) {
				break;
			}
			else {
				pos[heap[child1]] = heapPosition;
				pos[heap[heapPosition]] = child1;

				int aux = heap[child1];
				heap[child1] = heap[heapPosition];
				heap[heapPosition] = aux;

				heapPosition = child1;
				child1 = (heapPosition << 1) + 1;
				child2 = (heapPosition << 1) + 2;
			}
		}

		// daca exista ambii copii
		if (child2 < heapNr) {
			if (vec[heap[child1]] < vec[heap[child2]]) {
				if (vec[heap[heapPosition]] < vec[heap[child1]]) {
					break;
				}
				else {
					pos[heap[child1]] = heapPosition;
					pos[heap[heapPosition]] = child1;

					int aux = heap[child1];
					heap[child1] = heap[heapPosition];
					heap[heapPosition] = aux;

					heapPosition = child1;
					child1 = (heapPosition << 1) + 1;
					child2 = (heapPosition << 1) + 2;
				}
			}
			else {
				if (vec[heap[heapPosition]] < vec[heap[child2]]) {
					break;
				}
				else {
					pos[heap[child2]] = heapPosition;
					pos[heap[heapPosition]] = child2;

					int aux = heap[child2];
					heap[child2] = heap[heapPosition];
					heap[heapPosition] = aux;

					heapPosition = child2;
					child1 = (heapPosition << 1) + 1;
					child2 = (heapPosition << 1) + 2;
				}
			}
		}
	}
}

void addToHeap(int value) {
	int heapPosition = heapNr;

	vec[nr] = value;
	heap[heapNr] = nr;
	pos[nr] = heapNr;

	upheap(heapPosition);

	nr++;
	heapNr++;
}

void deleteFromHeap(int time) {
	// interschimb pozitiile pos[time], pos[heap[heapPosition]]
	// pozitia de la timpul time e interschimbata cu pozitia ultimei valori din heap
	int heapPosition = heapNr - 1;
	pos[heap[heapPosition]] = pos[time];

	// interschimb heap[pos[time]] u heap[heapPosition]
	// interschimb valoarea care trebuie stearsa cu ultima valoare din heap
	int aux = heap[pos[time]];
	heap[pos[time]] = heap[heapPosition];
	heap[heapPosition] = aux;

	heapNr--;

	// refacere heap in sus de la pozitia time
	int dad = (pos[time] - 1) >> 1;
	if (time != 0 && vec[heap[pos[time]]] < vec[heap[dad]]) {
		upheap(pos[time]);
	}

	// refacere heap in jos de la pozitia time
	else {
		downHeap(pos[time]);
	}
	pos[time] = -1;
}

int getMin() {
	return vec[heap[0]];
}

void debug() {
	printf("nr = %i\n", nr);
	printf("heapNr = %i\n", heapNr);
	for (int i = 0; i < heapNr; i++) {
		printf("%i ", vec[heap[i]]);
	}
	printf("\n\n");
}

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

	int n;
	scanf("%i", &n);
	for (int i = 0; i < n; i++) {
		int type;
		scanf("%i", &type);
		if (type == 1) {
			int x;
			scanf("%i", &x);
			addToHeap(x);
			//debug();
		}
		else if (type == 2) {
			int x;
			scanf("%i", &x);
			x--;
			deleteFromHeap(x);
			//debug();
		}
		else if (type == 3) {
			printf("%i\n", getMin());
		}
	}

	fclose(stdin);
	fclose(stdout);
	return 0;
}