Cod sursa(job #3319508)

Utilizator EckchartZgarcea Robert-Andrei Eckchart Data 1 noiembrie 2025 18:02:48
Problema Heapuri Scor 100
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.2 kb
#include "bits/stdc++.h"
using namespace std;
using ll = long long;
using ull = unsigned long long;
using ld = long double;
using pi = pair<int, int>;
using pll = pair<ll, ll>;
using pd = pair<double, double>;
using pld = pair<ld, ld>;
// #define LOCAL
#ifdef LOCAL
ifstream cin("input.txt");
ofstream cout("output2.txt");
#else
ifstream cin("heapuri.in");
ofstream cout("heapuri.out");
#endif
#define cin ::cin
#define cout ::cout
vector<int> idx_in_heap;
// .first - the value itself;
// .second - numarul de ordine (index) when the
// element was added into the heap.
vector<pi> my_heap;
// MAX HEAP


inline int parent(const int node)
{
    return node / 2;
}


inline int left_child(const int node)
{
    return node * 2;
}


inline int right_child(const int node)
{
    return node * 2 + 1;
}


inline int get_root()
{
    return my_heap[1].first;
}


// demote, basically (move down, AWAY FROM THE ROOT)
void sift(const int N, int xth_elem)
{
    // INDEX IN THE HEAP ITSELF, NOT THE Q-TH ELEMENT ADDED (FOR SOME NR. Q)
    int child_to_swap;
    while (true)
    {
        const int elem_heap_idx = idx_in_heap[xth_elem];
        child_to_swap = -1;
        if (right_child(elem_heap_idx) <= N
            && my_heap[elem_heap_idx].first < my_heap[right_child(elem_heap_idx)].first
            && my_heap[right_child(elem_heap_idx)].first > my_heap[left_child(elem_heap_idx)].first)
        {
            child_to_swap = right_child(elem_heap_idx);
        }
        if (left_child(elem_heap_idx) <= N
            && child_to_swap == -1
            && my_heap[elem_heap_idx].first < my_heap[left_child(elem_heap_idx)].first)
        {
            child_to_swap = left_child(elem_heap_idx);
        }
        if (child_to_swap == -1)
        {
            return;
        }

        // do the swap
        const pi temp_heap_to_swap = my_heap[child_to_swap];
        swap(my_heap[elem_heap_idx], my_heap[child_to_swap]);
        swap(idx_in_heap[xth_elem], idx_in_heap[temp_heap_to_swap.second]);
    }
}


// promote, basically (move up, TOWARDS THE ROOT)
void percolate(int xth_elem)
{
    int elem_heap_idx = idx_in_heap[xth_elem];
    while (elem_heap_idx > 1 && my_heap[elem_heap_idx].first > my_heap[parent(elem_heap_idx)].first)
    {
        const pi temp_heap_parent = my_heap[parent(elem_heap_idx)];
        swap(my_heap[elem_heap_idx], my_heap[parent(elem_heap_idx)]);
        swap(idx_in_heap[xth_elem], idx_in_heap[temp_heap_parent.second]);
        elem_heap_idx = idx_in_heap[xth_elem];
    }
}


void build_heap(int N)
{
    for (int i = N / 2; i > 0; --i)
    {
        sift(N, i);
    }
}


// K = index of node we will delete/remove
void cut(int &N, const int xth_elem)
{
    my_heap[idx_in_heap[xth_elem]] = my_heap[N];
    idx_in_heap[my_heap[N].second] = idx_in_heap[xth_elem];
    const int new_xth_elem = my_heap[N].second;
    const int new_elem_heap_idx = idx_in_heap[new_xth_elem];
    --N;

    // i think it's ok to have this, we should never access this elem again since it was deleted
    idx_in_heap[xth_elem] = -1;
    
    // we have swapped the node we should cut with the last node in the heap, by this point
    if (new_elem_heap_idx > 1 && my_heap[new_elem_heap_idx].first > my_heap[parent(new_elem_heap_idx)].first)
    {
        // need to move up
        percolate(new_xth_elem);
    }
    else
    {
        // *MIGHT* need to move down
        sift(N, new_xth_elem);
    }
}


void insert(int &N, const int val)
{
    static int pos = 0;
    ++N, ++pos;
    my_heap[N].first = val;
    my_heap[N].second = pos;
    idx_in_heap[pos] = N;
    percolate(pos);
}


int main()
{
    int N;
    cin >> N;
    my_heap.assign(N + 1, {1, -1});
    idx_in_heap.assign(N + 1, -1);
    int heap_size = 0;
    while (N--)
    {
        int op;
        cin >> op;
        if (op == 1)
        {
            int x;
            cin >> x;
            insert(heap_size, -x);
        }
        else if (op == 2)
        {
            int x;
            cin >> x;
            cut(heap_size, x);
        }
        else  // op = 3
        {
            cout << -get_root() << "\n";
        }
    }
}