Pagini recente » Cod sursa (job #3325076) | Cod sursa (job #3342482) | Cod sursa (job #1834734) | Cod sursa (job #3303513) | Cod sursa (job #3319503)
#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";
}
}
}