Pagini recente » Cod sursa (job #3314561) | Cod sursa (job #3314344) | Cod sursa (job #3335726) | Cod sursa (job #3349230) | Cod sursa (job #3303152)
#include <iostream>
#include <fstream>
#include <vector>
#include <cassert>
using namespace std;
struct MyHeap { // it's a min-heap
struct Node {
int value, id;
};
vector<Node*> nodes;
// Keeps track of where each node is in the heap
// The first element (index 0) is a dummy node to simplify calculations
vector<int> nodePosition;
int idCounter = 0;
// Constructor that initializes the heap with a bonus node to make indexing easier
MyHeap() {
nodes.push_back(new Node()); // dummy node at index 0
nodePosition.push_back(-1); // no valid position for dummy node
idCounter = 1; // start ids from 1
}
void balanceNode(int nodeIndex) {
int n = nodes.size() - 1;
if (nodeIndex < 1 || nodeIndex > n) return;
// Up-heap: check parent
while (nodeIndex > 1 && nodes[nodeIndex]->value < nodes[nodeIndex / 2]->value) {
swap(*nodes[nodeIndex], *nodes[nodeIndex / 2]);
nodePosition[nodes[nodeIndex]->id] = nodeIndex;
nodePosition[nodes[nodeIndex / 2]->id] = nodeIndex / 2;
nodeIndex /= 2;
}
// Down-heap: check children
while (true) {
int left = nodeIndex * 2;
int right = nodeIndex * 2 + 1;
int smallest = nodeIndex;
if (left <= n && nodes[left]->value < nodes[smallest]->value)
smallest = left;
if (right <= n && nodes[right]->value < nodes[smallest]->value)
smallest = right;
if (smallest != nodeIndex) {
swap(*nodes[nodeIndex], *nodes[smallest]);
nodePosition[nodes[nodeIndex]->id] = nodeIndex;
nodePosition[nodes[smallest]->id] = smallest;
nodeIndex = smallest;
} else {
break;
}
}
}
void insert(int value) {
// to insert we insert at the end of the heap and then balance it
Node* newNode = new Node;
newNode->value = value;
newNode->id = idCounter++; // assign a unique id to the new node
nodePosition.push_back(nodes.size()); // add the new node's id to the position mapping
assert(nodePosition[newNode->id] == nodes.size()); // ensure the position is correct
nodes.push_back(newNode);
balanceNode(nodes.size() - 1);
}
~MyHeap() {
for (Node* node : nodes) {
delete node;
}
}
int getMin() const {
if (nodes.size() <= 1) return -1; // heap is empty
return nodes[1]->value; // the root node contains the minimum value
}
void printHeap(ostream& out) const {
for (size_t i = 1; i < nodes.size(); ++i) {
out << nodes[i]->value << " ";
}
out << endl;
}
void erase(int id) {
// // debug output:
// cerr << "Erasing node with id: " << id << " at position: " << nodePosition[id] << " with value: " << nodes[nodePosition[id]]->value << endl;
if (id < 1 || id >= idCounter) return; // invalid id
int pos = nodePosition[id];
int last = nodes.size() - 1;
if (pos == last) {
// If the node to be removed is the last node, just remove it
delete nodes[last];
nodes.pop_back();
nodePosition[id] = -1; // mark as invalid
return;
}
// Replace the node with the last node
swap(*nodes[pos], *nodes[last]);
nodePosition[nodes[pos]->id] = pos; // update the position of the node being moved
nodePosition[nodes[last]->id] = -1; // mark the last node as invalid
delete nodes.back(); // remove the last node
nodes.pop_back();
// cout << "Nothing went wrong until now." << endl;
// Update the position mapping
// nodePosition[nodes[nodePosition[id]]->id] = id;
// Balance the node at index id
balanceNode(pos);
// // debug output:
// cerr << "After erasing, heap is: ";
// printHeap(cerr);
}
void removeMin() {
// uses erase
if (nodes.size() <= 1) return; // heap is empty
erase(nodes[1]->id);
}
};
int main() {
ifstream fin("heapuri.in");
ofstream fout("heapuri.out");
int q;
fin >> q;
MyHeap heap;
for (int i = 0; i < q; ++i) {
// 1 - insert
// 2 - remove by id
// 3 - get minimum
int type, value;
fin >> type;
if (type == 1) {
fin >> value;
heap.insert(value);
} else if (type == 2) {
fin >> value;
heap.erase(value);
} else if (type == 3) {
fout << heap.getMin() << endl;
}
}
return 0;
}