Cod sursa(job #3319503)

Utilizator EckchartZgarcea Robert-Andrei Eckchart Data 1 noiembrie 2025 17:20:56
Problema Heapuri Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 4.57 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, nrs;
// .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)
{
    int child_to_swap;  // INDEX IN THE HEAP ITSELF, NOT THE NTH ELEMENT ADDED
    while (true)
    {
        child_to_swap = -1;
        if (right_child(idx_in_heap[xth_elem]) <= N
            && my_heap[idx_in_heap[xth_elem]].first < my_heap[right_child(idx_in_heap[xth_elem])].first
            && my_heap[right_child(idx_in_heap[xth_elem])].first > my_heap[left_child(idx_in_heap[xth_elem])].first)
        {
            child_to_swap = right_child(idx_in_heap[xth_elem]);
        }
        if (left_child(idx_in_heap[xth_elem]) <= N
            && child_to_swap == -1
            && my_heap[idx_in_heap[xth_elem]].first < my_heap[left_child(idx_in_heap[xth_elem])].first)
        {
            child_to_swap = left_child(idx_in_heap[xth_elem]);
        }
        if (child_to_swap == -1)
        {
            return;
        }

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


// promote, basically (move up, TOWARDS THE ROOT)
void percolate(int xth_elem)
{
    while (idx_in_heap[xth_elem] > 1 && my_heap[idx_in_heap[xth_elem]].first > my_heap[parent(idx_in_heap[xth_elem])].first)
    {
        // const pi temp_heap_child = my_heap[idx_in_heap[xth_elem]];
        const pi temp_heap_parent = my_heap[parent(idx_in_heap[xth_elem])];
        swap(my_heap[idx_in_heap[xth_elem]], my_heap[parent(idx_in_heap[xth_elem])]);
        swap(idx_in_heap[xth_elem], idx_in_heap[temp_heap_parent.second]);
        // idx_in_heap[xth_elem] = parent(idx_in_heap[xth_elem]);
        // xth_elem = parent(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;

    // 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;
    // idx_in_heap[N] = K;
    // swap(idx_in_heap[xth_elem], my_heap[N].second);
    N--;
    
    // we have swapped the node we should cut with the last node in the heap, by this point
    if (idx_in_heap[new_xth_elem] > 1 && my_heap[idx_in_heap[new_xth_elem]].first > my_heap[parent(idx_in_heap[new_xth_elem])].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)
{
    ++N;
    static int pos = 1;
    my_heap[N].first = val;
    my_heap[N].second = pos;
    idx_in_heap[pos] = N;
    ++pos;
    percolate(N);
}


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