Cod sursa(job #2772145)

Utilizator radu.z5Zamfirescu Radu Ioan radu.z5 Data 30 august 2021 21:11:10
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.69 kb
#include <fstream>
#include <climits>
#include <unordered_map>
#include <vector>

using namespace std;

int parent(const int i) {
    return (i - 1) >> 1;
}

int leftChild(const int i) {
    return (i << 1) + 1;
}

int rightChild(const int i) {
    return (i << 1) + 2;
}

void siftUp(vector<int> &heap, int idx, unordered_map<int, int> &pos) {
    while (idx > 0) {
        int up = parent(idx);

        if (heap[idx] < heap[up]) {
            swap(pos[heap[idx]], pos[heap[up]]);
            swap(heap[idx], heap[up]);
            idx = up;
        } else {
            break;
        }
    }
}

void siftDown(vector<int> &heap, int idx, unordered_map<int, int> &pos) {
    while (true) {
        size_t left = leftChild(idx);
        size_t right = rightChild(idx);

        int smallestId = idx;
        if (left < heap.size() && heap[left] < heap[smallestId])
            smallestId = left;
        if (right < heap.size() && heap[right] < heap[smallestId])
            smallestId = right;
        if (smallestId == idx)
            break;

        swap(pos[heap[smallestId]], pos[heap[idx]]);
        swap(heap[smallestId], heap[idx]);
        idx = smallestId;
    }
}

void push(vector<int> &heap, int x, unordered_map<int, int> &pos) {
    pos[x] = heap.size();
    heap.push_back(x);
    siftUp(heap, pos[x], pos);
}

// sterge al x-lea element inserat in multime
void withdraw(vector<int> &heap, int x, unordered_map<int, int> &pos,
            int *ord) {
    int idToDelete = pos[ord[x]];
    swap(pos[ord[x]], pos[heap.back()]);
    swap(heap[idToDelete], heap.back());
    heap.pop_back();
    if (heap.size() > 1 && idToDelete < ((int) heap.size())) {
        if (idToDelete > 0 && heap[idToDelete] < heap[parent(idToDelete)]) {
            siftUp(heap, idToDelete, pos);
        } else {
            siftDown(heap, idToDelete, pos);
        }
    }
}

void solve(ifstream &in, ofstream &out) {
    int n;
    in >> n;

    vector<int> heap;
    unordered_map<int, int> pos;

    // retine ordinea inserarii elementelor
    int ord[n], inserted = 0;

    heap.reserve(n);
    pos.reserve(n);

    int op, x;

    for (int i = 0; i < n; i++) {
        in >> op;

        switch (op) {
            case 1:
                in >> x;
                ord[++inserted] = x;
                push(heap, x, pos);
                break;
            case 2:
                in >> x;
                withdraw(heap, x, pos, ord);
                break;
            case 3:
                out << heap[0] << "\n";
                break;
            default:
                break;
        }
    }
}

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

    solve(in, out);

    in.close();
    out.close();
    return 0;
}