Cod sursa(job #3303152)

Utilizator ArdeleanOficialAlexandru ArdeleanOficial Data 14 iulie 2025 12:45:24
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.83 kb
#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;
}