Cod sursa(job #2462795)

Utilizator preda.andreiPreda Andrei preda.andrei Data 27 septembrie 2019 20:16:06
Problema Heapuri Scor 10
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.24 kb
#include <fstream>
#include <vector>

using namespace std;

class Heap
{
public:
    void Add(int num);
    void Remove(int xth);

    int Min() const { return heap_[0].first; }

private:
    static int Father(int node) { return (node - 1) / 2; }
    static int LeftSon(int node) { return 2 * node + 1; }
    static int RightSon(int node) { return 2 * node + 2; }

    void Sift(int node);
    void Percolate(int node);
    void Swap(int node_a, int node_b);

    using Elem = pair<int, int>;

    vector<Elem> heap_;
    vector<int> pos_;
};

void Heap::Add(int num)
{
    pos_.push_back(heap_.size());
    heap_.push_back({num, pos_.size() - 1});

    Percolate(heap_.size() - 1);
}

void Heap::Remove(int xth)
{
    int pos_to_remove = pos_[xth];
    Swap(pos_to_remove, heap_.size() - 1);

    heap_.pop_back();
    if (heap_.empty()) {
        return;
    }

    if (pos_to_remove > 0 && heap_[Father(pos_to_remove)].first > heap_[pos_to_remove].first) {
        Percolate(pos_to_remove);
    } else {
        Sift(pos_to_remove);
    }
}

void Heap::Sift(int node)
{
    int left = LeftSon(node);
    if (left >= (int)heap_.size()) {
        return;
    }

    int best = left;
    int right = RightSon(node);

    if (right < (int)heap_.size()) {
        best = right;
    }

    if (heap_[best].first < heap_[node].first) {
        Swap(best, node);
        Sift(best);
    }
}

void Heap::Percolate(int node)
{
    if (node <= 0) {
        return;
    }

    int father = Father(node);
    if (heap_[father].first > heap_[node].first) {
        Swap(father, node);
        Percolate(father);
    }
}

void Heap::Swap(int node_a, int node_b)
{
    int xth_a = heap_[node_a].second;
    int xth_b = heap_[node_b].second;

    swap(pos_[xth_a], pos_[xth_b]);
    swap(heap_[node_a], heap_[node_b]);
}

int main()
{
    ifstream fin("heapuri.in");
    ofstream fout("heapuri.out");

    int queries;
    fin >> queries;

    Heap heap;
    for (int i = 0; i < queries; i += 1) {
        int type, value;
        fin >> type;

        if (type == 1) {
            fin >> value;
            heap.Add(value);
        } else if (type == 2) {
            fin >> value;
            heap.Remove(value - 1);
        } else {
            fout << heap.Min() << "\n";
        }
    }
    return 0;
}