Cod sursa(job #2595324)

Utilizator MicuMicuda Andrei Micu Data 7 aprilie 2020 15:44:29
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.37 kb
#pragma once
#include <queue>
#include <iostream>
#include <vector>
#include <stack>
#include <utility>
#include <map>
class Node {
	int val;
	Node* nextSibling;
	Node* firstChild;
	static int nrOfNodes;
public:
	Node(int val);
	void addChild(Node* node);
	friend class PairingHeap;
};

class PairingHeap {
	Node* root;
	static std::map<int, bool> deleted;
public:
	PairingHeap();
	PairingHeap(int val); //creates a heap with one element(used for insertion)
	PairingHeap(Node* root); //initializes a heap with another node(used for deletion)
	int getMin();
	void show();
	int size();
	void build(const std::vector<int>& v);
	void insert(int val);
	void deleteMin();
	void deleteVal(int val);
	friend PairingHeap& merge(PairingHeap& heap1, PairingHeap& heap2);
};

/*// NODE IMPLEMENTATION //*/
int Node::nrOfNodes = 0;

Node::Node(int val):val(val), nextSibling(nullptr), firstChild(nullptr){
	nrOfNodes++;
}

void Node::addChild(Node* node) {
	if (this->firstChild == nullptr)
		this->firstChild = node;
	else {
		node->nextSibling = this->firstChild;
		this->firstChild = node;
	}
}

/*// PAIRING HEAP IMPLEMENTATION //*/
std::map<int, bool> PairingHeap::deleted;

PairingHeap::PairingHeap():root(nullptr){}

PairingHeap::PairingHeap(int val) {
	this->root = new Node(val);
}

PairingHeap::PairingHeap(Node* root):root(root){}

void PairingHeap::build(const std::vector<int>& v) {
	for (int i = 0; i < v.size(); i++) {
		this->insert(v[i]);
	}
}

int PairingHeap::getMin() {
	return root->val;
}

int PairingHeap::size() {
	return Node::nrOfNodes;
}

void PairingHeap::show() {
	std::queue<std::pair <Node*, int>> node_queue;
	node_queue.push(std::make_pair(this->root, 0));
	std::vector<int> parents[21];
	while (!node_queue.empty()) {
		Node* curr_node = node_queue.front().first;
		int parent = node_queue.front().second;
		node_queue.pop();
		do {
			parents[parent].push_back(curr_node->val);
			//if I can go down from this node, I add it's child to the queue
			if (curr_node->firstChild != nullptr) {
				node_queue.push(std::make_pair(curr_node->firstChild, curr_node->val));
			}
			curr_node = curr_node->nextSibling;
		} while (curr_node != nullptr);
	}
	for(int i = 0; i < 21; i++) {
		std::cout << i << ": ";
		for (int j = 0; j < parents[i].size(); j++) {
			std::cout << parents[i][j] << ' ';
		}
		std::cout << '\n';
	}
}

void PairingHeap::insert(int val) {
	PairingHeap tmp(val);
	(*this) = merge((*this), tmp);
}

PairingHeap& merge(PairingHeap& heap1, PairingHeap& heap2){
	if (heap1.root == nullptr) return heap2;
	if (heap2.root == nullptr) return heap1;

	if (heap1.getMin() < heap2.getMin()) {
		heap1.root->addChild(heap2.root);
		return heap1;
	}
	else {
		heap2.root->addChild(heap1.root);
		return heap2;
	}
}

void PairingHeap::deleteMin() {
	Node* childOfRoot = this->root->firstChild;
	std::queue<Node*> subHeaps;
	while (childOfRoot != nullptr) {
		subHeaps.push(childOfRoot);
		Node* tmp = childOfRoot->nextSibling;
		childOfRoot->nextSibling = nullptr;
		childOfRoot = tmp;

	}
	std::stack<Node*> firstTraversal;
	while (subHeaps.size() > 1) {
		PairingHeap heap1(subHeaps.front());
		subHeaps.pop();
		PairingHeap heap2(subHeaps.front());
		subHeaps.pop();
		firstTraversal.push(merge(heap1, heap2).root);
	}
	if (subHeaps.size() == 1) {
		firstTraversal.push(subHeaps.front());
		subHeaps.pop();
	}

	this->root = nullptr;
	while (!firstTraversal.empty()) {
		PairingHeap tmpHeap(firstTraversal.top());
		(*this) = merge((*this), tmpHeap);
		firstTraversal.pop();
	}
	//if the new minimum has been marked for deletion by lazy deletion, we delete the minimum again
	if (this->root != nullptr && deleted[this->root->val])
		this->deleteMin();
}

void PairingHeap::deleteVal(int val) {
	if (this->root->val == val) {
		this->deleteMin();
	}
	else {
		deleted[val] = 1;
	}
}

#include <fstream>

std::ifstream in("heapuri.in");
std::ofstream out("heapuri.out");

int main() {
	int n;
	PairingHeap p;
	std::vector<int> ord_val;
	in >> n;
	for (int i = 0; i < n; i++) {
		int op;
		in >> op;
		if (op == 1) {
			int val;
			in >> val;
			p.insert(val);
			ord_val.push_back(val);
		}
		else if (op == 2) {
			int poz;
			in >> poz;
			int val = ord_val[poz - 1];
			p.deleteVal(val);
		}
		else {
			out << p.getMin() << '\n';
		}
	}
	return 0;
}