Cod sursa(job #3130217)

Utilizator DevCrutCorolevschi Mihai DevCrut Data 17 mai 2023 01:40:52
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 3.72 kb
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,f16c,fma,sse3,ssse3,sse4.1,sse4.2") 

#include <iostream>
#include <fstream>
#include <vector>

using namespace std;

ifstream myIn("heapuri.in");
ofstream myOut("heapuri.out");

class MyHeap {
private:
    vector<int> elements;
    vector<int> positions;
    vector<int> values;
    int valuesCount = 0;
    
    int _parent(int index) {
        return index / 2;
    }
    int _right(int index) {
        return index * 2 + 1;
    }
    int _left(int index) {
        return index * 2;
    }

    void _heapifyUp(int index) {
        while (index != 0 && this->values[this->elements[this->_parent(index)]] > this->values[this->elements[index]]) {
            int posIndexA = this->elements[index];
            int posIndexB = this->elements[this->_parent(index)];
            this->elements[index] = posIndexB;
            this->elements[this->_parent(index)] = posIndexA;

            int inter = this->positions[posIndexA];
            this->positions[posIndexA] = this->positions[posIndexB];
            this->positions[posIndexB] = inter;
            
            index = this->_parent(index);
        }
    }
    void _heapifyDown(int index) {
        int pusher = index;
        int left = this->_left(index);
        int right = this->_right(index);

        if (left < this->elements.size() && this->values[this->elements[left]] < this->values[this->elements[pusher]])
            pusher = left;

        if (right < this->elements.size() && this->values[this->elements[right]] < this->values[this->elements[pusher]])
            pusher = right;


        if (pusher != index) {
            int posIndexA = this->elements[index];
            int posIndexB = this->elements[pusher];
            this->elements[index] = posIndexB;
            this->elements[pusher] = posIndexA;

            int inter = this->positions[posIndexA];
            this->positions[posIndexA] = this->positions[posIndexB];
            this->positions[posIndexB] = inter;

            this->_heapifyDown(pusher);
        }
    }
public:
    void insert(int elem) {
        this->values[valuesCount] = elem;
        this->positions[valuesCount] = elements.size();
        this->elements.push_back(valuesCount);
        ++valuesCount;
        this->_heapifyUp(this->elements.size() - 1);
    }
    void remove(int timeframe) {
        int heapPos = this->positions[timeframe];

        int posIndexA = this->elements[heapPos];
        int posIndexB = this->elements[this->elements.size() - 1];
        this->elements[heapPos] = posIndexB;
        this->elements[this->elements.size() - 1] = posIndexA;

        int inter = this->positions[posIndexA];
        this->positions[posIndexA] = this->positions[posIndexB];
        this->positions[posIndexB] = inter;

        this->elements.pop_back();

        if (this->elements.size() != heapPos) {
            this->_heapifyUp(heapPos);
            this->_heapifyDown(heapPos);
        }
    }
    int top() {
        return this->values[this->elements[0]];
    }



    MyHeap() {
        this->positions.resize(200000, -1);
        this->values.resize(200000, -1);
    }
};

int main() {
    ios_base::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);

    int n;
    myIn >> n;

    MyHeap heap;
    for (int i = 0; i < n; ++i) {
        int x;
        myIn >> x;
        if (x == 3) {
            myOut << heap.top() << '\n';
        }
        else {
            int y;
            myIn >> y;
            if (x == 1) {
                heap.insert(y);
            }
            else if(x == 2) {
                heap.remove(y - 1);
            }
        }
    }
    
    return 0;
}