This documentation is automatically generated by competitive-verifier/competitive-verifier
#include "structure/others/priority-sum-structure.hpp"PrioritySumStructure は、要素の追加・削除を行いながら、優先度の高い $k$ 個の総和を管理するデータ構造です。
MaximumSum は大きい方から $k$ 個、MinimumSum は小さい方から $k$ 個の総和を管理します。
template <typename T>
using MaximumSum = PrioritySumStructure<T, std::greater<T>, std::less<T>>;
template <typename T>
using MinimumSum = PrioritySumStructure<T, std::less<T>, std::greater<T>>;
PrioritySumStructure<T>(int k)
優先度の高い $k$ 個の総和を管理するデータ構造を初期化します。
T query() const
現在の要素のうち、優先度の高い $k$ 個の総和を返します。
MaximumSum では大きい方から $k$ 個、MinimumSum では小さい方から $k$ 個の総和を返します。
T kth_element()
現在の $k$ 番目 (1-indexed) の要素を返します。
MaximumSum では $k$ 番目に大きい値、MinimumSum では $k$ 番目に小さい値を返します。
void insert(T x)
要素 $x$ を追加します。
void erase(T x)
要素 $x$ を 1 つ削除します。
void set_k(std::size_t kk)
管理する要素の個数を kk に変更します。
std::size_t get_k() const
現在の $k$ を返します。
std::size_t size() const
現在の要素数を返します。
#pragma once
#include <cassert>
#include <cstddef>
#include <functional>
#include <queue>
#include <vector>
template <typename T, typename Compare = std::less<T>,
typename RCompare = std::greater<T>>
struct PrioritySumStructure {
std::size_t k;
T sum;
std::priority_queue<T, std::vector<T>, Compare> in, d_in;
std::priority_queue<T, std::vector<T>, RCompare> out, d_out;
PrioritySumStructure(int k) : k(k), sum(0) {}
void modify() {
while (in.size() - d_in.size() < k && !out.empty()) {
auto p = out.top();
out.pop();
if (!d_out.empty() && p == d_out.top()) {
d_out.pop();
} else {
sum += p;
in.emplace(p);
}
}
while (in.size() - d_in.size() > k) {
auto p = in.top();
in.pop();
if (!d_in.empty() && p == d_in.top()) {
d_in.pop();
} else {
sum -= p;
out.emplace(p);
}
}
while (!d_in.empty() && in.top() == d_in.top()) {
in.pop();
d_in.pop();
}
}
T query() const { return sum; }
T kth_element() {
assert(0 < k && k <= size());
modify();
return in.top();
}
void insert(T x) {
in.emplace(x);
sum += x;
modify();
}
void erase(T x) {
assert(size());
if (!in.empty() && in.top() == x) {
sum -= x;
in.pop();
} else if (!in.empty() && RCompare()(in.top(), x)) {
sum -= x;
d_in.emplace(x);
} else {
d_out.emplace(x);
}
modify();
}
void set_k(std::size_t kk) {
k = kk;
modify();
}
std::size_t get_k() const { return k; }
std::size_t size() const {
return in.size() + out.size() - d_in.size() - d_out.size();
}
};
template <typename T>
using MaximumSum = PrioritySumStructure<T, std::greater<T>, std::less<T>>;
template <typename T>
using MinimumSum = PrioritySumStructure<T, std::less<T>, std::greater<T>>;
#line 2 "structure/others/priority-sum-structure.hpp"
#include <cassert>
#include <cstddef>
#include <functional>
#include <queue>
#include <vector>
template <typename T, typename Compare = std::less<T>,
typename RCompare = std::greater<T>>
struct PrioritySumStructure {
std::size_t k;
T sum;
std::priority_queue<T, std::vector<T>, Compare> in, d_in;
std::priority_queue<T, std::vector<T>, RCompare> out, d_out;
PrioritySumStructure(int k) : k(k), sum(0) {}
void modify() {
while (in.size() - d_in.size() < k && !out.empty()) {
auto p = out.top();
out.pop();
if (!d_out.empty() && p == d_out.top()) {
d_out.pop();
} else {
sum += p;
in.emplace(p);
}
}
while (in.size() - d_in.size() > k) {
auto p = in.top();
in.pop();
if (!d_in.empty() && p == d_in.top()) {
d_in.pop();
} else {
sum -= p;
out.emplace(p);
}
}
while (!d_in.empty() && in.top() == d_in.top()) {
in.pop();
d_in.pop();
}
}
T query() const { return sum; }
T kth_element() {
assert(0 < k && k <= size());
modify();
return in.top();
}
void insert(T x) {
in.emplace(x);
sum += x;
modify();
}
void erase(T x) {
assert(size());
if (!in.empty() && in.top() == x) {
sum -= x;
in.pop();
} else if (!in.empty() && RCompare()(in.top(), x)) {
sum -= x;
d_in.emplace(x);
} else {
d_out.emplace(x);
}
modify();
}
void set_k(std::size_t kk) {
k = kk;
modify();
}
std::size_t get_k() const { return k; }
std::size_t size() const {
return in.size() + out.size() - d_in.size() - d_out.size();
}
};
template <typename T>
using MaximumSum = PrioritySumStructure<T, std::greater<T>, std::less<T>>;
template <typename T>
using MinimumSum = PrioritySumStructure<T, std::less<T>, std::greater<T>>;