Cod sursa(job #2638516)

Utilizator CiobaCatalinCioba Catalin CiobaCatalin Data 28 iulie 2020 15:34:08
Problema Heapuri Scor 40
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.97 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <unordered_map>

using namespace std;

class heap {

	void upheap(int index) {
		while (index > 1 && data[index] < data[get_parent(index)]) {
			swap(index, get_parent(index));
			index = get_parent(index);
		}	
	}

	void downheap(int index) {
		if (index >= data.size()) {
			return;
		}
		int left_child = get_left_child(index);
		int right_child = get_right_child(index);

		int min_child = -1;
		if (left_child < data.size()) {
			min_child = left_child;
		}
		if (right_child < data.size() && data[right_child] < data[left_child]) {
			min_child = right_child;
		}

		if (min_child > -1 && data[index] > data[min_child]) {
			swap(index, min_child);
			downheap(min_child);
		}
	}	

	int get_parent(int index) {
		return index / 2;
	}

	int get_left_child(int index) {
		return 2 * index;
	}

	int get_right_child(int index) {
		return 2 * index + 1;
	}

	void swap(int left, int right) {
		int left_nth = positions_inverse[left];
		int right_nth = positions_inverse[right];
		
		positions[left_nth] = right;
		positions[right_nth] = left;
		positions_inverse[left] = right_nth;
		positions_inverse[right] = left_nth;
		
		int tmp = data[left];
		data[left] = data[right];
		data[right] = tmp;
	}

public:
	heap() {
		data.push_back(9999);
		count = 0;
	}

	void add(int num) {
		data.push_back(num);
		count++;

		positions[count] = data.size() - 1;
		positions_inverse[data.size() - 1] = count;

		upheap(data.size() - 1);
	}

	void remove(int nth) {
		int position = positions[nth];
		data[position] = data[data.size() - 1];
		
		positions_inverse[position] = positions_inverse[data.size() - 1];
		positions.erase(nth);
		positions_inverse.erase(data.size() - 1);

		data.pop_back();
		downheap(position);
	}

	int min() {
		return data[1];
	}

	void print() {
		cout << "data: ";
		for (int i = 0; i < data.size(); i++) {
			cout << data[i] << " ";
		}
		cout << endl << "positions: ";
		for (auto const& v : positions) {
			cout << "[" << v.first << ": " << v.second << "] ";
		}
		cout << endl << "positions_inverse: ";
		for (auto const& v : positions_inverse) {
			cout << "[" << v.first << ": " << v.second << "] ";
		}
		cout << endl << endl;
	}
private:
	vector<int> data;
	unordered_map<int,int> positions;
	unordered_map<int,int> positions_inverse;
	int count;
};

int main()
{
	//ifstream in("heapuri.in");
    	//ofstream out("heapuri.out");
	FILE* fin = fopen("heapuri.in", "r");
	FILE* fout = fopen("heapuri.out", "w");

	int n;
	//in >> n;
	fscanf(fin, "%i", &n);

	heap h;

	for (int i = 0; i < n; i++) {
		int x;
		int num; 

		fscanf(fin, "%i", &x);
		
		if (x == 1) {
			//in >> num;
			fscanf(fin, "%i", &num);
			h.add(num);
		} else if ( x == 2) {
			//in >> num; 
			fscanf(fin, "%i", &num);
			h.remove(num);
		} else {
			//out << h.min() << endl;
			fprintf(fout, "%i\n", h.min());
		}
	}
}