This documentation is automatically generated by online-judge-tools/verification-helper
#include "ds/segtree/beats_summin_chmax.hpp"
#include "ds/segtree/segtree_beats.hpp"
template <typename T>
struct Beats_SumMin_Chmax {
struct SumMin {
struct X {
T sum, min, minc, min2;
bool fail;
};
using value_type = X;
static X op(const X& x, const X& y) {
if (x.min == infty<T>) return y;
if (y.min == infty<T>) return x;
X z;
z.sum = x.sum + y.sum;
z.min = min(x.min, y.min);
z.minc = (x.min == z.min ? x.minc : 0) + (y.min == z.min ? y.minc : 0);
z.min2 = infty<T>;
if (z.min < x.min && x.min < z.min2) z.min2 = x.min;
if (z.min < x.min2 && x.min2 < z.min2) z.min2 = x.min2;
if (z.min < y.min && y.min < z.min2) z.min2 = y.min;
if (z.min < y.min2 && y.min2 < z.min2) z.min2 = y.min2;
z.fail = 0;
return z;
}
static constexpr X unit() { return {0, infty<T>, 0, infty<T>, 0}; }
bool commute = true;
};
struct AddChmax {
using X = pair<T, T>;
using value_type = X;
static constexpr X op(const X& x, const X& y) {
auto [a, c] = x;
auto [d, f] = y;
a += d, c += d, c = max(c, f);
return {a, c};
}
static constexpr X unit() { return {0, -infty<T>}; }
bool commute = false;
};
struct Beats {
using Monoid_X = SumMin;
using Monoid_A = AddChmax;
using X = typename Monoid_X::value_type;
using A = typename Monoid_A::value_type;
static X act(X& x, const A& a, int cnt) {
assert(!x.fail);
if (x.min == infty<T>) return x;
auto [add, ma] = a;
x.sum += cnt * add, x.min += add, x.min2 += add;
if (ma == -infty<T>) return x;
T before_min = x.min;
x.min = max(x.min, ma);
if (x.minc == cnt) { x.min2 = x.min, x.sum = cnt * x.min; }
elif (x.min2 > x.min) { x.sum += (x.min - before_min) * x.minc; }
else {
x.fail = 1;
}
return x;
}
};
using X = typename SumMin::X;
SegTree_Beats<Beats> seg;
Beats_SumMin_Chmax(vc<T>& A) {
seg.build(len(A), [&](int i) -> X { return from_element(A[i]); });
}
template <typename F>
Beats_SumMin_Chmax(int n, F f) {
seg.build(n, [&](int i) -> X { return from_element(f(i)); });
}
void set(int i, T x) { seg.set(i, from_element(x)); }
// (sum, min)
pair<T, T> prod(int l, int r) {
auto e = seg.prod(l, r);
return {e.sum, e.min};
}
static X from_element(T x) { return {x, x, 1, x}; }
void chmax(int l, int r, T x) { seg.apply(l, r, {0, x}); }
void add(int l, int r, T x) { seg.apply(l, r, {x, -infty<T>}); }
};