Cod sursa(job #2710127)

Utilizator vnedelcuVictor Andrei Nedelcu vnedelcu Data 21 februarie 2021 21:15:52
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.62 kb
#include <stdio.h>
#include <vector>

using namespace std;

class MinHeap {
private:
    int no_insertions;
    vector<int> elements;
    vector<int> insert_order_to_heap_position;
    vector<int> heap_position_to_insert_order;

    int left_son(int node) {return node << 1;}
    int right_son(int node) {return (node << 1) | 1;}
    int father(int node) {return node >> 1;}
    void up_heap(int node);
    void down_heap(int node);

public:
    int capacity;
    int heap_size;

    MinHeap(int capacity);
    void insert(int val);
    void remove_kth_inserted(int k);
    int get_min();
};

MinHeap::MinHeap(int capacity) {
    no_insertions = 0;
    heap_size = 0;
    this->capacity = capacity;
    elements.resize(capacity + 1);
    insert_order_to_heap_position.resize(capacity + 1);
    heap_position_to_insert_order.resize(capacity + 1);
}

void MinHeap::up_heap(int node) {
    int node_father = father(node);
    while (node_father && elements[node] < elements[node_father]) {
        swap(
             insert_order_to_heap_position[heap_position_to_insert_order[node]],
             insert_order_to_heap_position[heap_position_to_insert_order[node_father]]
        );
        swap(elements[node], elements[node_father]);
        swap(heap_position_to_insert_order[node], heap_position_to_insert_order[node_father]);

        node = node_father;
        node_father = father(node_father);
    }
}

void MinHeap::down_heap(int node) {
    while (true) {
        int min_son = 0;
        if (left_son(node) <= heap_size) {
            min_son = left_son(node);

            if (
                right_son(node) <= heap_size &&
                elements[min_son] > elements[right_son(node)]
            ) {
                min_son = right_son(node);
            }
        }

        if (!min_son || elements[node] < elements[min_son]) {
            break;
        }

        swap(
             insert_order_to_heap_position[heap_position_to_insert_order[node]],
             insert_order_to_heap_position[heap_position_to_insert_order[min_son]]
        );
        swap(elements[node], elements[min_son]);
        swap(heap_position_to_insert_order[node], heap_position_to_insert_order[min_son]);

        node = min_son;
    }
}

void MinHeap::insert(int val) {
    ++no_insertions;
    ++heap_size;

    elements[heap_size] = val;
    insert_order_to_heap_position[no_insertions] = heap_size;
    heap_position_to_insert_order[heap_size] = no_insertions;

    up_heap(heap_size);
}

void MinHeap::remove_kth_inserted(int k) {
    int node = insert_order_to_heap_position[k];

    elements[node] = elements[heap_size];
    heap_position_to_insert_order[node] = heap_position_to_insert_order[heap_size];
    insert_order_to_heap_position[heap_position_to_insert_order[heap_size]] = node;

    --heap_size;

    if (node > 1 && elements[father(node)] > elements[node]) {
        up_heap(node);
    } else {
        down_heap(node);
    }
}

int MinHeap::get_min() {
    return elements[1];
}

int main() {
    FILE * fin, * fout;
    int n, op, x;

    fin = fopen("heapuri.in", "r");
    fout = fopen("heapuri.out", "w");

    fscanf(fin, "%d", &n);
    MinHeap heap(n);
    for (int i = 0; i < n; i++) {
        fscanf(fin, "%d", &op);

        if (op == 1) {
            fscanf(fin, "%d", &x);
            heap.insert(x);
        } else if (op == 2) {
            fscanf(fin, "%d", &x);
            heap.remove_kth_inserted(x);
        } else {
            fprintf(fout, "%d\n", heap.get_min());
        }
    }

    fclose(fin);
    fclose(fout);

    return 0;
}