Pagini recente » Cod sursa (job #2585552) | Cod sursa (job #1814938) | Cod sursa (job #2713679) | Cod sursa (job #2335244) | Cod sursa (job #2485154)
#include <fstream>
#include <bitset>
#include <sys/mman.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include <unistd.h>
using namespace std;
class parser {
public:
inline parser() {
/// default c-tor
}
inline parser(const char* file_name) {
int fd = open(file_name, O_RDONLY);
index &= 0;
fstat(fd, &sb);
buffer = (char*)mmap(0, sb.st_size, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, fd, 0);
close(fd);
}
template <typename T>
inline parser& operator >> (T& n) {
n &= 0;
#ifdef SIGNED
sign &= 0;
sign = (buffer[index - 1] == '-');
#endif
for (; buffer[index] < '0' or buffer[index] > '9'; ++index);
for (; '0' <= buffer[index] and buffer[index] <= '9'; ++index)
n = (n << 3) + (n << 1) + buffer[index] - '0';
#ifdef SIGNED
n ^= ((n ^ -n) & -sign);
#endif
return *this;
}
~parser() {
munmap(buffer, sb.st_size);
}
private:
struct stat sb;
int index;
#ifdef SIGNED
int sign;
#endif
char* buffer;
};
class writer{
public:
writer() {};
writer(const char *file_name){
output_file.open(file_name,ios::out | ios::binary);
output_file.sync_with_stdio(false);
index&=0;}
[[gnu::hot]] inline writer &operator <<(int target){
aux&=0;
n=target;
if (!n)
nr[aux++]='0';
for (;n;n/=10)
nr[aux++]=n%10+'0';
for(;aux;inc())
buffer[index]=nr[--aux];
return *this;}
inline writer &operator <<(const char *target){
aux&=0;
while (target[aux])
buffer[index]=target[aux++],inc();
return *this;}
~writer(){
output_file.write(buffer,index);output_file.close();}
private:
fstream output_file;
static const int SIZE=0x400000; ///2MB
int index,aux,n;
char buffer[SIZE],nr[24];
inline void inc(){
if(++index==SIZE)
index&=0,output_file.write(buffer,SIZE);}
};
#pragma once
template <class _elem, typename is_less_than>
class heap { /// expects functor
/// compare is expected to return bool value
/// by-default min_heap, change compare function accordingly
public:
heap(size_t _size = 1000) {
max_size = _size;
storage = new _elem[max_size];
current_bound = 1;
current_size = 0;
} /// default c-tor
heap(const heap<_elem, is_less_than>& target) {
*this = target;
} /// copy c-tor
heap& operator = (const heap<_elem, is_less_than>& target) {
delete[] storage;
max_size = target.max_size;
storage = new _elem[max_size];
for (unsigned i = 0; i < max_size; ++i)
storage[i] = target.storage[i];
current_size = target.current_size;
current_bound = target.current_bound;
} /// copy assgn
[[gnu::hot]] void add(_elem target) {
storage[current_bound] = target;
sift_up(current_bound);
++current_bound;
++current_size;
}
[[gnu::pure]] bool empty() { return (current_size == 0); }
[[gnu::pure]] _elem top() { return storage[1]; }
[[gnu::hot]] _elem pop() {
unsigned iterator = 1;
_elem retval = storage[iterator];
while (!is_leaf(iterator)) {
if (comparator(left_son(iterator), right_son(iterator)))
storage[iterator] = left_son(iterator),
iterator = left_son_pos(iterator);
else
storage[iterator] = right_son(iterator),
iterator = right_son_pos(iterator);
}
storage[iterator] = storage[--current_bound];
--current_size;
return retval;
}
/*
void run_diagnostic() {
for (unsigned i = 1; i < current_bound; ++i)
std::cout << storage[i] << " ";
std::cout << std::endl;
}
*/
~heap() { delete[] storage; }
private:
void sift_up(unsigned pos) {
unsigned target = parent_pos(pos);
_elem aux = storage[pos];
while (target && comparator(aux, storage[target])) {
storage[pos] = storage[target];
pos = target;
target = parent_pos(pos);
}
storage[pos] = aux;
}
[[gnu::hot, gnu::pure]] inline unsigned right_son_pos(unsigned pos) {
return 1 + (pos << 1);
}
[[gnu::hot, gnu::pure]] inline _elem right_son(unsigned pos) {
return storage[right_son_pos(pos)];
}
[[gnu::hot, gnu::pure]] inline unsigned left_son_pos(unsigned pos) {
return (pos << 1);
}
[[gnu::hot, gnu::pure]] inline _elem left_son(unsigned pos) {
return storage[left_son_pos(pos)];
}
[[gnu::hot]] inline unsigned parent_pos(unsigned pos) {
return (pos >> 1);
}
[[gnu::hot]] inline _elem parent(unsigned pos) {
return storage[parent_pos(pos)];
}
[[gnu::hot]] inline int is_leaf(unsigned pos) {
if (right_son_pos(pos) < current_bound &&
left_son_pos(pos) < current_bound) {
return 0;
}
//else if (right_son_pos(pos) == current_bound) { // empty right_leaf
// return -1;
//}
else {
return 1;
}
}
is_less_than comparator;
size_t max_size, current_size, current_bound;
_elem* storage;
};
class integer{
public:
int elem, index;
struct do_compare {
[[gnu::hot, gnu::pure]] inline bool operator () (integer const &a, integer const &b) {
return a.elem < b.elem;
}
};
};
parser f ("heapuri.in");
writer t ("heapuri.out");
int n;
bitset <200010> vaz;
heap<integer, integer::do_compare> h(200010);
integer maneuver;
int main() {
f >> n;
maneuver.index &= 0;
#pragma ivdep
for (int query, i = 0; i < n; ++i) {
f >> query;
switch (query) {
case 1: {
f >> maneuver.elem;
++maneuver.index;
h.add(maneuver);
break;
}
case 2: {
f >> query;
vaz[query] = true;
break;
}
case 3: {
while(vaz[h.top().index]) {
h.pop();
}
t << h.top().elem << "\n";
break;
}
}
}
return 0;
}