This documentation is automatically generated by online-judge-tools/verification-helper
#include "data_structure/slope_trick.hpp"#pragma once
#include <cassert>
#include <limits>
#include <queue>
#include <type_traits>
template <typename T>
class SlopeTrick {
public:
static constexpr T MIN = std::numeric_limits<T>::min() / 2;
static constexpr T MAX = std::numeric_limits<T>::max() / 2;
private:
template <bool REV>
class PriorityQueue {
std::priority_queue<
T,
std::vector<T>,
typename std::conditional<REV, std::greater<T>, std::less<T>>::type>
pq;
T added;
public:
PriorityQueue() : pq(), added(0) {
if constexpr (REV)
pq.push(MAX);
else
pq.push(MIN);
}
void push(const T &x) {
pq.push(x - added);
}
void add(const T &x) {
added += x;
}
T top() const {
return pq.top() + added;
}
T pop() {
T ret = pq.top();
pq.pop();
return ret += added;
}
void clear() {
while (pq.size() > 1)
pq.pop();
}
};
PriorityQueue<false> l;
PriorityQueue<true> r;
T minimum;
public:
SlopeTrick() : l(), r(), minimum(T(0)) {}
T min() const {
return minimum;
}
std::pair<T, T> min_arg() const {
return std::pair<T, T>(l.top(), r.top());
}
void add_constant(const T &a) {
minimum += a;
}
void add_plus(const T &a) {
if (l.top() > a) {
minimum += l.top() - a;
l.push(a);
r.push(l.pop());
} else {
r.push(a);
}
}
void add_minus(const T &a) {
if (r.top() < a) {
minimum += a - r.top();
r.push(a);
l.push(r.pop());
} else {
l.push(a);
}
}
void add_abs(const T &a) {
add_plus(a);
add_minus(a);
}
void clear_left() {
l.clear();
}
void clear_right() {
r.clear();
}
void slide_min(const T &a, const T &b) {
assert(a <= b);
l.add(a);
r.add(b);
}
void slide(const T &a) {
l.add(a);
r.add(a);
}
};#line 2 "data_structure/slope_trick.hpp"
#include <cassert>
#include <limits>
#include <queue>
#include <type_traits>
template <typename T>
class SlopeTrick {
public:
static constexpr T MIN = std::numeric_limits<T>::min() / 2;
static constexpr T MAX = std::numeric_limits<T>::max() / 2;
private:
template <bool REV>
class PriorityQueue {
std::priority_queue<
T,
std::vector<T>,
typename std::conditional<REV, std::greater<T>, std::less<T>>::type>
pq;
T added;
public:
PriorityQueue() : pq(), added(0) {
if constexpr (REV)
pq.push(MAX);
else
pq.push(MIN);
}
void push(const T &x) {
pq.push(x - added);
}
void add(const T &x) {
added += x;
}
T top() const {
return pq.top() + added;
}
T pop() {
T ret = pq.top();
pq.pop();
return ret += added;
}
void clear() {
while (pq.size() > 1)
pq.pop();
}
};
PriorityQueue<false> l;
PriorityQueue<true> r;
T minimum;
public:
SlopeTrick() : l(), r(), minimum(T(0)) {}
T min() const {
return minimum;
}
std::pair<T, T> min_arg() const {
return std::pair<T, T>(l.top(), r.top());
}
void add_constant(const T &a) {
minimum += a;
}
void add_plus(const T &a) {
if (l.top() > a) {
minimum += l.top() - a;
l.push(a);
r.push(l.pop());
} else {
r.push(a);
}
}
void add_minus(const T &a) {
if (r.top() < a) {
minimum += a - r.top();
r.push(a);
l.push(r.pop());
} else {
l.push(a);
}
}
void add_abs(const T &a) {
add_plus(a);
add_minus(a);
}
void clear_left() {
l.clear();
}
void clear_right() {
r.clear();
}
void slide_min(const T &a, const T &b) {
assert(a <= b);
l.add(a);
r.add(b);
}
void slide(const T &a) {
l.add(a);
r.add(a);
}
};