Mai intai trebuie sa te autentifici.

Cod sursa(job #1093731)

Utilizator cdt2014Cont de Teste cdt2014 Data 28 ianuarie 2014 15:37:29
Problema Heapuri Scor 10
Compilator cpp Status done
Runda Arhiva educationala Marime 1.87 kb
#include <algorithm>
#include <fstream>
#include <iostream>
#include <map>
#include <vector>
using namespace std;

class Heap {
public:
	Heap() {
		v.resize(200000);
		fill(v.begin(), v.end(), -1);
		used = 0;
	}

	
	void insert(int x) {
		v[used] = x;
		pos[x] = used;
		used ++;
		pushup(pos[x]);
	}

	int min() {
		return v[0];
	}

	void remove(int x) {
		int p = pushdown(pos[x]);
		if (p != used-1) {
			this->swap(p, used-1);
			v[used - 1] = -1;
			pos.erase(x);
			pushup(p);
		} else {
			pos.erase(x);
			v[p] = -1;
		}
		used --;
	}
private:
	vector<int> v;
	map<int, int> pos;
	int used;

	int pushdown(int p) {
#ifdef __DEBUG__
		cout << p << ": ";
		print();
		cout << endl;
#endif
		if (2*p+1 >= v.size()) { // no valid son
			pos.erase(v[p]);
			return p;
		}
		int son = v[2*p+1] > 0 ? 2*p+1 : 2*p+2; // left, if exists, otherwise right
		if (v[son] < 0) { // if no valid son, return
			pos.erase(v[p]);
			return p;
		}

		if (2*p+2 < v.size() && v[2*p+2] > 0 && v[2*p+2] < v[son]) {
			son = 2*p+2;
		}

		this->swap(son, p);
		return pushdown(son);
	}

	int pushup(int p) {
#ifdef __DEBUG__		
		cout << p << "# ";
		print();
		cout << endl;
#endif
		if (p == 0) return 0;
		
		int t = p / 2;
		if (v[t] > v[p]) {
			this->swap(p, t);
			return pushup(t);
		}

		return p;
	}

	void swap(int p1, int p2) {
		int v1 = v[p1],
			v2 = v[p2];

		std::swap(pos[v1], pos[v2]);
		std::swap(v[p1], v[p2]);
	}

	void print() {
		for (int i=0; i<used; ++i) {
			cout << v[i] << " ";
		}
	}
};

int main() {
	ifstream in("heapuri.in");
	ofstream out("heapuri.out");
	int nq;
	Heap h;
	vector<int> chron;

	in >> nq;
	while (nq --) {
		int op, val;
		in >> op;
		switch (op) {
			case 1: 
				in >> val;
				chron.push_back(val);
				h.insert(val);
				break;
			case 2: 
				in >> val;
				h.remove(chron[val-1]);
				break;
			case 3:
				out << h.min() << "\n";
				break;
		}
	}
	out.close();
	return 0;
}