You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
value_type _prod_section(int l, int r, std::optional<key_type> a, std::optional<key_type> b) const {
95
-
value_type ret = e();
82
+
value_type ret = cumulative_value[r - 1];
96
83
if (b.has_value()) {
97
84
int i = std::lower_bound(key_data.begin() + l, key_data.begin() + r, b.value(), comp) - key_data.begin();
98
85
if (i != l) {
99
86
ret = cumulative_value[i - 1];
87
+
} else {
88
+
ret = e();
100
89
}
101
-
} else {
102
-
ret = cumulative_value[r - 1];
103
90
}
104
91
if (a.has_value()) {
105
92
int i = std::lower_bound(key_data.begin() + l, key_data.begin() + r, a.value(), comp) - key_data.begin();
@@ -109,24 +96,6 @@ class MergeSortTree {
109
96
}
110
97
return ret;
111
98
}
112
-
value_type _prod(int l, int r, std::optional<key_type> a, std::optional<key_type> b) const {
113
-
value_type ret = e();
114
-
int h = height - 1;
115
-
int t = 1;
116
-
while (l < r) {
117
-
if (l & t) {
118
-
ret = op(ret, _prod_section(h * sz + l, h * sz + l + t, a, b));
119
-
l += t;
120
-
}
121
-
if (r & t) {
122
-
r -= t;
123
-
ret = op(ret, _prod_section(h * sz + r, h * sz + r + t, a, b));
124
-
}
125
-
h--;
126
-
t <<= 1;
127
-
}
128
-
return ret;
129
-
}
130
99
131
100
public:
132
101
MergeSortTree() = default;
@@ -155,11 +124,31 @@ class MergeSortTree {
155
124
156
125
/**
157
126
* @brief product value[i] s.t. a <= key[i] < b , i in [l, r)
127
+
*
128
+
* @param l 半開区間の開始
129
+
* @param r 半開区間の終端 0<=l<=r<=n
130
+
* @param a nulloptの場合は負の無限大
131
+
* @param b nulloptの場合は正の無限大
158
132
*/
159
-
value_type prod(std::optional<int> l = std::nullopt, std::optional<int> r = std::nullopt, std::optional<key_type> a = std::nullopt, std::optional<key_type> b = std::nullopt) const {
160
-
if (a.has_value() and b.has_value() andnotcomp(a.value(), b.value())) returne();
161
-
if (l.has_value() and r.has_value() and l >= r) returne();
162
-
return_prod(l.value_or(0), r.value_or(n), a, b);
133
+
value_type prod(int l, int r, std::optional<key_type> a = std::nullopt, std::optional<key_type> b = std::nullopt) const {
134
+
assert(0 <= l && l <= r && r <= n);
135
+
if (a.has_value() && b.has_value() && !comp(a.value(), b.value())) returne();
136
+
value_type ret = e();
137
+
int h = height - 1;
138
+
int t = 1;
139
+
while (l < r) {
140
+
if (l & t) {
141
+
ret = op(ret, _prod_section(h * sz + l, h * sz + l + t, a, b));
142
+
l += t;
143
+
}
144
+
if (r & t) {
145
+
r -= t;
146
+
ret = op(ret, _prod_section(h * sz + r, h * sz + r + t, a, b));
0 commit comments