-
Notifications
You must be signed in to change notification settings - Fork 11
/
Copy pathrange-affine-range-sum.test.cpp
62 lines (57 loc) · 2.24 KB
/
range-affine-range-sum.test.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#include "../../modint.hpp"
#include "../range-update-range-get.hpp"
#include <utility>
#define PROBLEM "https://judge.yosupo.jp/problem/range_affine_range_sum"
// RangeAffineRangeSum
// - update: x_i -> a * x_i + b for i in [l, r)
// - get: return x_l + ... + x_{r - 1}
template <typename T>
struct RangeAffineRangeSum : public LazySegmentTree<std::pair<T, int>, std::pair<T, T>, T, bool> {
using TDATA = std::pair<T, int>;
using TLAZY = std::pair<T, T>;
using SegTree = LazySegmentTree<TDATA, TLAZY, T, bool>;
void merge_data(int pos) {
this->data[pos].first = this->data[pos * 2].first + this->data[pos * 2 + 1].first;
this->data[pos].second = this->data[pos * 2].second + this->data[pos * 2 + 1].second;
}
void reflect_lazy(int pos) {
if (pos < this->head) {
overlap_lazy(pos * 2, this->lazy[pos]);
overlap_lazy(pos * 2 + 1, this->lazy[pos]);
}
this->data[pos].first = this->lazy[pos].first * this->data[pos].first +
this->lazy[pos].second * this->data[pos].second;
this->lazy[pos] = this->zero_lazy;
}
void overlap_lazy(int pos, const TLAZY &d) {
this->lazy[pos] = std::make_pair(
this->lazy[pos].first * d.first, this->lazy[pos].second * d.first + d.second);
}
T data2ret(int pos, const bool &) { return this->data[pos].first; }
T merge_ret(const T &l, const T &r, const bool &) { return l + r; }
RangeAffineRangeSum(const std::vector<T> &seq) : SegTree::LazySegmentTree() {
std::vector<std::pair<T, int>> vinit;
for (auto x : seq) vinit.emplace_back(x, 1);
SegTree::initialize(vinit, std::make_pair(0, 0), std::make_pair(1, 0), T(0));
};
};
using mint = ModInt<998244353>;
int main() {
std::cin.tie(nullptr), std::ios::sync_with_stdio(false);
int N, Q;
std::cin >> N >> Q;
std::vector<mint> A(N);
for (auto &a : A) std::cin >> a;
RangeAffineRangeSum<mint> segtree(A);
while (Q--) {
int q, l, r;
std::cin >> q >> l >> r;
if (q) {
std::cout << segtree.get(l, r) << '\n';
} else {
mint b, c;
std::cin >> b >> c;
segtree.update(l, r, std::make_pair(b, c));
}
}
}