Pagini recente » Cod sursa (job #1058613) | Cod sursa (job #2184174) | Cod sursa (job #1714538) | Cod sursa (job #102010) | Cod sursa (job #2178084)
/**
* References
*
* https://queue.acm.org/detail.cfm?id=1814327
* http://phk.freebsd.dk/B-Heap/
*/
#include <stdint.h>
#include <stdio.h>
#define SIZE 200704
struct elem {
int x, ins_time;
};
static unsigned h_psize, h_shift, h_mask, h_hmask, h_num_elem, h_algo;
static unsigned at_n;
static struct elem h[SIZE];
static int ins_time_to_h_pos[SIZE];
static inline unsigned h_po(unsigned idx)
{
/* return offset inside page of element at idx */
return (idx & h_mask);
}
static void h_bubble_up(unsigned idx, struct elem v)
{
unsigned idx_of_parent, po;
struct elem parent_value;
while (idx > 1) {
if (h_algo == 1) {
idx_of_parent = idx >> 1;
} else {
po = h_po(idx);
if (idx < h_psize || po > 3) {
idx_of_parent = (idx & ~h_mask) | (po >> 1);
} else if (po < 2) {
idx_of_parent = (idx - h_psize) >> h_shift;
idx_of_parent += (idx_of_parent & ~h_hmask);
idx_of_parent |= h_psize / 2;
} else {
idx_of_parent = idx - 2;
}
}
parent_value = h[idx_of_parent];
if (parent_value.x < v.x)
return;
h[idx_of_parent] = v;
ins_time_to_h_pos[h[idx_of_parent].ins_time] = idx_of_parent;
h[idx] = parent_value;
ins_time_to_h_pos[h[idx].ins_time] = idx;
idx = idx_of_parent;
}
}
static void h_bubble_down(unsigned idx, struct elem v)
{
unsigned i1, i2;
struct elem v1, v2;
while (idx < h_num_elem) {
if (h_algo == 1) {
i1 = i2 = idx << 1;
i2++;
} else {
if (idx > h_mask && !(idx & (h_mask - 1))) {
/* first two elements in nonzero pages */
i1 = i2 = idx + 2;
} else if (idx & (h_psize >> 1)) {
/* Last row of page */
i1 = (idx & ~h_mask) >> 1;
i1 |= idx & (h_mask >> 1);
i1 += 1;
i1 <<= h_shift;
i2 = i1 + 1;
} else {
i1 = idx + (idx & h_mask);
i2 = i1 + 1;
}
}
if (i1 != i2 && i2 <= h_num_elem) {
v1 = h[i1];
v2 = h[i2];
if (v1.x < v.x && v1.x <= v2.x) {
h[i1] = v;
ins_time_to_h_pos[h[i1].ins_time] = i1;
h[idx] = v1;
ins_time_to_h_pos[h[idx].ins_time] = idx;
idx = i1;
} else if (v2.x < v.x) {
h[i2] = v;
ins_time_to_h_pos[h[i2].ins_time] = i2;
h[idx] = v2;
ins_time_to_h_pos[h[idx].ins_time] = idx;
idx = i2;
} else {
break;
}
} else if (i1 <= h_num_elem) {
v1 = h[i1];
if (v1.x < v.x) {
h[i1] = v;
ins_time_to_h_pos[h[i1].ins_time] = i1;
h[idx] = v1;
ins_time_to_h_pos[h[idx].ins_time] = idx;
idx = i1;
} else {
break;
}
} else
break;
}
}
static void h_insert(unsigned val)
{
h_num_elem++;
at_n++;
h[h_num_elem].ins_time = at_n;
h[h_num_elem].x = val;
ins_time_to_h_pos[at_n] = h_num_elem;
h_bubble_up(h_num_elem, h[h_num_elem]);
}
static void h_remove(unsigned ins_time)
{
h[ins_time_to_h_pos[ins_time]] = h[h_num_elem];
ins_time_to_h_pos[h[h_num_elem].ins_time] = ins_time_to_h_pos[ins_time];
h_num_elem--;
if (h_num_elem == 0)
return;
h_bubble_down(ins_time_to_h_pos[ins_time], h[ins_time_to_h_pos[ins_time]]);
}
int main(void)
{
int n = 0, ch, x;
freopen("heapuri.in", "r", stdin);
freopen("heapuri.out", "w", stdout);
h_shift = 9;
h_mask = 511;
h_hmask = h_mask >> 1;
h_num_elem = 0;
h_psize = 512;
h_algo = 1;
while ((ch = getchar()) != '\n') {
n = n * 10 + ch - '0';
}
while (n--) {
ch = getchar();
getchar();
x = 0;
if (ch == '1') {
while ((ch = getchar()) != '\n') {
x = x * 10 + (ch - '0');
}
h_insert(x);
} else if (ch == '2') {
while ((ch = getchar()) != '\n') {
x = x * 10 + (ch - '0');
}
h_remove(x);
} else {
printf("%d\n", h[1].x);
}
}
return 0;
}