This documentation is automatically generated by online-judge-tools/verification-helper
View the Project on GitHub kmyk/competitive-programming-library
/**
* @brief a double-ended priority queue
* @note the feature is the same to std::multiset, but this is 7x faster for 10^7 operations
* @note interval heap is more faster
* @sa https://topcoder.g.hatena.ne.jp/spaghetti_source/20121006#c1349522933
*/
template <class T>
class four_priority_queues {
priority_queue<T> max_heap, max_deleted;
priority_queue<T, vector<T>, greater<T> > min_heap, min_deleted;
private:
template <class Queue>
void flush(Queue & heap, Queue & deleted) {
while (not deleted.empty()) {
assert (not heap.empty());
if (deleted.top() != heap.top()) break;
deleted.pop();
heap.pop();
}
}
public:
void push(T a) {
max_heap.push(a);
min_heap.push(a);
}
T get_min() {
flush(min_heap, min_deleted);
return min_heap.top();
}
T get_max() {
flush(max_heap, max_deleted);
return max_heap.top();
}
void pop_min() {
max_deleted.push(get_min());
min_heap.pop();
}
void pop_max() {
min_deleted.push(get_max());
max_heap.pop();
}
bool empty() {
flush(min_heap, min_deleted); // NOTE: you can replace this with max_*
return min_heap.empty();
}
};
unittest {
default_random_engine gen;
REP (iteration, 10) {
four_priority_queues<int> depq;
multiset<int> mlt;
REP (iteration, 100000) {
if (mlt.empty() or bernoulli_distribution(0.8)(gen)) {
int a = uniform_int_distribution<int>()(gen);
mlt.insert(a);
depq.push(a);
} else {
if (bernoulli_distribution(0.5)(gen)) {
int a = *mlt.begin();
int b = depq.get_min();
assert (a == b);
mlt.erase(mlt.begin());
depq.pop_min();
} else {
int a = *prev(mlt.end());
int b = depq.get_max();
assert (a == b);
mlt.erase(prev(mlt.end()));
depq.pop_max();
}
}
}
}
}
#line 1 "old/double-ended-priority-queue.inc.cpp"
/**
* @brief a double-ended priority queue
* @note the feature is the same to std::multiset, but this is 7x faster for 10^7 operations
* @note interval heap is more faster
* @sa https://topcoder.g.hatena.ne.jp/spaghetti_source/20121006#c1349522933
*/
template <class T>
class four_priority_queues {
priority_queue<T> max_heap, max_deleted;
priority_queue<T, vector<T>, greater<T> > min_heap, min_deleted;
private:
template <class Queue>
void flush(Queue & heap, Queue & deleted) {
while (not deleted.empty()) {
assert (not heap.empty());
if (deleted.top() != heap.top()) break;
deleted.pop();
heap.pop();
}
}
public:
void push(T a) {
max_heap.push(a);
min_heap.push(a);
}
T get_min() {
flush(min_heap, min_deleted);
return min_heap.top();
}
T get_max() {
flush(max_heap, max_deleted);
return max_heap.top();
}
void pop_min() {
max_deleted.push(get_min());
min_heap.pop();
}
void pop_max() {
min_deleted.push(get_max());
max_heap.pop();
}
bool empty() {
flush(min_heap, min_deleted); // NOTE: you can replace this with max_*
return min_heap.empty();
}
};
unittest {
default_random_engine gen;
REP (iteration, 10) {
four_priority_queues<int> depq;
multiset<int> mlt;
REP (iteration, 100000) {
if (mlt.empty() or bernoulli_distribution(0.8)(gen)) {
int a = uniform_int_distribution<int>()(gen);
mlt.insert(a);
depq.push(a);
} else {
if (bernoulli_distribution(0.5)(gen)) {
int a = *mlt.begin();
int b = depq.get_min();
assert (a == b);
mlt.erase(mlt.begin());
depq.pop_min();
} else {
int a = *prev(mlt.end());
int b = depq.get_max();
assert (a == b);
mlt.erase(prev(mlt.end()));
depq.pop_max();
}
}
}
}
}