区間 [l, r) について sum(min(A_i, x)) / sum(max(A_i, x)) を求める
lib/data_structure/range_min_max_sum.hpp
インクルード
#include "data_structure/range_min_max_sum.hpp"
クラス
| 名前 | 説明 |
|---|---|
RangeMinMaxSum |
区間 [l, r) について sum(min(A_i, x)) / sum(max(A_i, x)) を求める |
検証
依存するヘッダ(3)
-
キー区間に含まれる重みの総和も扱うウェーブレット行列
lib/data_structure/wavelet_matrix_rectangle_sum.hpp -
完備辞書
lib/internal/internal_bit_vector.hpp -
ウェーブレット行列の共通コア(各 level のビットベクトル型を差し替え可能にする)
lib/internal/wavelet_matrix_base.hpp
検証プログラム(1)
-
test/yukicoder/2065.test.cpp
test/yukicoder/2065.test.cpp
実装
#pragma once
#include <vector>
#include "data_structure/wavelet_matrix_rectangle_sum.hpp"
/// @brief 区間 [l, r) について sum(min(A_i, x)) / sum(max(A_i, x)) を求める
/// @complexity 構築は $O(nL)$、問い合わせは $O(L)$
template <class T, class U = T, int L = 30>
struct RangeMinMaxSum {
/// @brief 空のデータ構造を作る
/// @complexity $O(1)$
RangeMinMaxSum() = default;
/// @brief 列 `v` からデータ構造を構築する
/// @complexity $O(nL)$
explicit RangeMinMaxSum(const std::vector<T> &v) : wm(v, v) {}
/// @brief $\sum_{i=l}^{r-1}\min(v_i,x)$ を返す
/// @complexity $O(L)$
U query_min(int l, int r, T x) const {
auto [cnt, sum] = wm.rect_count_sum(l, r, x + 1);
return sum + U(x) * U(r - l - cnt);
}
/// @brief $\sum_{i=l}^{r-1}\max(v_i,x)$ を返す
/// @complexity $O(L)$
U query_max(int l, int r, T x) const { return wm.total_sum(l, r) + U(x) * U(r - l) - query_min(l, r, x); }
private:
WaveletMatrixRectangleSum<T, U, L> wm;
};