Cod sursa(job #1453755)

Utilizator GilgodRobert B Gilgod Data 24 iunie 2015 16:32:41
Problema Heapuri Scor 100
Compilator cpp Status done
Runda Arhiva educationala Marime 2.16 kb
#include <iostream>
#include <fstream>
#include <assert.h>
#include <cstring>

#define INF 0x3f3f3f3f

#define father(nod) (nod/2)
#define left_son(nod) (nod*2)
#define right_son(nod) (nod*2+1)

const char IN[] = "heapuri.in", OUT[] = "heapuri.out";
const int NMAX = 200001;

using namespace std;

int v[NMAX];			//valorile originale
int heap[NMAX];			//indexi pentru heap
int idx[NMAX];			//idx[x] = nod in heap
int N, OP;
int order;

void percolate(int k) {
	//se muta nodul in sus prin arbore pana la radacina/pana 
	//parintele e mai mic ca el
	while (father(k) > 0 && v[heap[k]] < v[heap[father(k)]]) {
		swap(heap[k], heap[father(k)]);
		idx[heap[k]] = k;
		idx[heap[father(k)]] = father(k);
		k = father(k);
	}
}

void sift(int k) {
	int son;
	//se muta k in jos in arbore pana la pozitia corecta
	do {
		son = 0;
		// se ia un copil mai mic ca el
		if (left_son(k) <= N) {
			if (v[heap[left_son(k)]] < v[heap[k]])
				son = left_son(k);
		}
		if (right_son(k) <= N) {
			if (v[heap[right_son(k)]] < v[heap[k]]
				&& v[heap[right_son(k)]] < v[heap[left_son(k)]])
				son = right_son(k);
		}
		if (son) {
			swap(heap[k], heap[son]);
			idx[heap[k]] = k;
			idx[heap[son]] = son;
			k = son;
		}
	} while (son);
}

inline void read_data() {
	assert(freopen(IN, "r", stdin));
	assert(scanf("%d", &OP));
	memset(v, INF, sizeof(v));
	assert(freopen(OUT, "w", stdout));
	for (int i = 0; i < OP; ++i) {
		int o, x;
		scanf("%d", &o);
		switch (o) {
		case 1:
			assert(scanf("%d", &x));
			++order, ++N;
			v[order] = x;			//order = ordinea cronologica
			idx[order] = N;			//idx: ord cronologica <-> ord heap	
			heap[N] = order;		//N = ordinea din heap
			percolate(N);			
			break;
		case 3:
			printf("%d\n", v[heap[1]]);
			break;
		case 2:
			assert(scanf("%d", &x));
			v[x] = -1;
			percolate(idx[x]);
			//nodul de eliminat e in radacina acum
			idx[heap[1]] = 0;
			//se muta ultimul element din heap in locul sau
			swap(heap[1], heap[N]), --N;
			idx[heap[1]] = 1;
			//se muta in jos la o pozitie corecta
			sift(1);
		}
	}
	fclose(stdout);
	fclose(stdin);
}

int main() {
	read_data();
	return 0;
}