Pagini recente » Cod sursa (job #3355133) | Cod sursa (job #3335953) | Cod sursa (job #3337223) | Cod sursa (job #3339295) | Cod sursa (job #3319508)
#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";
}
}
}