Cod sursa(job #3130797)

Utilizator darius1843Darius Suditu darius1843 Data 18 mai 2023 17:18:53
Problema Heapuri cu reuniune Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.11 kb
#include <fstream>
#include <list>
#include <queue>

using namespace std;
ifstream in("mergeheap.in");
ofstream out("mergeheap.out");

class BinomialHeap {
private:
    class Node {
    public:
        int value;
        int grad;
        Node* child;
        Node* sibling;
        Node* parent;

        Node() : value(0), grad(0), child(nullptr), sibling(nullptr), parent(nullptr) {}
        Node(int val) : value(val), grad(0), child(nullptr), sibling(nullptr), parent(nullptr) {}
    };

    list<Node*> heap;

    Node* mergetree(Node* t1, Node* t2) {
        if (t2->value > t1->value) {
            swap(t1, t2);
        }

        t2->sibling = t1->child;
        t1->grad++;
        t2->parent = t1;
        t1->child = t2;

        return t1;
    }

    void adjust() {
        if (heap.size() <= 1) {
            return;
        }

        heap.sort([](Node* a, Node* b) {
            return a->grad < b->grad;
            });

        auto ant = heap.begin();
        auto curr = ant;
        auto urm = curr;
        urm++;

        while (curr != heap.end()) {
            if (urm != heap.end() && (*ant)->grad == (*curr)->grad && (*curr)->grad == (*urm)->grad) {
                ant = heap.erase(ant);
                *ant = mergetree(*ant, *curr);
                curr = heap.erase(curr);
                urm++;
            }
            else if ((*ant)->grad == (*curr)->grad) {
                *ant = mergetree(*ant, *curr);
                curr = heap.erase(curr);
                urm++;
            }
            else {
                ant++;
                curr++;
                urm++;
            }
        }
    }

public:
    void insert(int val) {
        Node* tree = new Node(val);
        heap.push_back(tree);
        adjust();
    }

    void MergeHeap(BinomialHeap& heap2) {
        list<Node*> heapFinal;

        Node* h1_node = heap.empty() ? nullptr : heap.front();
        Node* h2_node = heap2.heap.empty() ? nullptr : heap2.heap.front();

        while (h1_node != nullptr && h2_node != nullptr) {
            if (h1_node->grad <= h2_node->grad) {
                heapFinal.push_back(h1_node);
                heap.pop_front();
                h1_node = heap.empty() ? nullptr : heap.front();
            }
            else {
                heapFinal.push_back(h2_node);
                heap2.heap.pop_front();
                h2_node = heap2.heap.empty() ? nullptr : heap2.heap.front();
            }
        }

        while (h1_node != nullptr) {
            heapFinal.push_back(h1_node);
            heap.pop_front();
            h1_node = heap.empty() ? nullptr : heap.front();
        }

        while (h2_node != nullptr) {
            heapFinal.push_back(h2_node);
            heap2.heap.pop_front();
            h2_node = heap2.heap.empty() ? nullptr : heap2.heap.front();
        }

        heap = heapFinal;
        adjust();
    }

    int extract_max() {
        if (heap.empty()) {
            throw runtime_error("Heap is empty");
        }

        Node* max_node = nullptr;
        for (Node* n : heap) {
            if (max_node == nullptr || n->value > max_node->value) {
                max_node = n;
            }
        }

        int max_value = max_node->value;
        heap.remove(max_node);

        Node* child = max_node->child;
        while (child != nullptr) {
            Node* sibling = child->sibling;
            child->sibling = nullptr;
            heap.push_front(child);
            child = sibling;
        }

        adjust();
        return max_value;
    }
};

int N, Q, nop, poz1, poz2;
BinomialHeap heap[105];

int main() {
    in >> N >> Q;
    for (int i = 1; i <= Q; i++) {
        in >> nop;
        if (nop == 1) {
            in >> poz1 >> poz2;
            heap[poz1].insert(poz2);
        }
        else if (nop == 2) {
            in >> poz1;
            out << heap[poz1].extract_max() << endl;
        }
        else if (nop == 3) {
            in >> poz1 >> poz2;
            heap[poz1].MergeHeap(heap[poz2]);
        }
    }

    return 0;
}