55#include < intrin.h>
66#endif
77
8+ #if __cplusplus >= 202002L
9+ #include < bit>
10+ #endif
11+
812namespace atcoder {
913
1014namespace internal {
1115
12- // @param n `0 <= n`
13- // @return minimum non-negative `x` s.t. `n <= 2**x`
14- int ceil_pow2 (int n) {
15- int x = 0 ;
16- while ((1U << x) < (unsigned int )(n)) x++;
16+ #if __cplusplus >= 202002L
17+
18+ using std::bit_ceil;
19+
20+ #else
21+
22+ // @return same with std::bit::bit_ceil
23+ unsigned int bit_ceil (unsigned int n) {
24+ unsigned int x = 1 ;
25+ while (x < (unsigned int )(n)) x *= 2 ;
1726 return x;
1827}
1928
29+ #endif
30+
2031// @param n `1 <= n`
21- // @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`
22- int bsf (unsigned int n) {
32+ // @return same with std::bit::countr_zero
33+ int countr_zero (unsigned int n) {
2334#ifdef _MSC_VER
2435 unsigned long index;
2536 _BitScanForward (&index, n);
@@ -29,6 +40,14 @@ int bsf(unsigned int n) {
2940#endif
3041}
3142
43+ // @param n `1 <= n`
44+ // @return same with std::bit::countr_zero
45+ constexpr int countr_zero_constexpr (unsigned int n) {
46+ int x = 0 ;
47+ while (!(n & (1 << x))) x++;
48+ return x;
49+ }
50+
3251} // namespace internal
3352
3453} // namespace atcoder
@@ -37,24 +56,31 @@ int bsf(unsigned int n) {
3756#ifndef ATCODER_LAZYSEGTREE_HPP
3857#define ATCODER_LAZYSEGTREE_HPP 1
3958
40- #include < algorithm>
4159#include < cassert>
42- #include < iostream >
60+ #include < functional >
4361#include < vector>
4462
45- // #include "atcoder/internal_bit"
63+ #include " atcoder/internal_bit"
4664
4765namespace atcoder {
4866
49- template <class S , S (*op)(S, S), S (*e)(), class F , S (*mapping)(F, S), F (*composition)(F, F),
50- F (*id)()>
67+ template <class S , auto op, auto e, class F , auto mapping, auto composition, auto id>
5168struct lazy_segtree {
69+ static_assert (std::is_convertible_v<decltype (op), std::function<S(S, S)>>,
70+ " op must work as S(S, S)" );
71+ static_assert (std::is_convertible_v<decltype (e), std::function<S()>>, " e must work as S()" );
72+ static_assert (std::is_convertible_v<decltype (mapping), std::function<S(F, S)>>,
73+ " mapping must work as S(F, S)" );
74+ static_assert (std::is_convertible_v<decltype (composition), std::function<F(F, F)>>,
75+ " composition must work as F(F, F)" );
76+ static_assert (std::is_convertible_v<decltype (id), std::function<F()>>, " id must work as F()" );
77+
5278public:
5379 lazy_segtree () : lazy_segtree(0 ) {}
5480 explicit lazy_segtree (int n) : lazy_segtree(std::vector<S>(n, e())) {}
5581 explicit lazy_segtree (const std::vector<S> &v) : _n(int (v.size())) {
56- log = internal::ceil_pow2 (_n );
57- size = 1 << log ;
82+ size = ( int ) internal::bit_ceil (( unsigned int )(_n) );
83+ log = internal::countr_zero (( unsigned int )size) ;
5884 d = std::vector<S>(2 * size, e ());
5985 lz = std::vector<F>(size, id ());
6086 for (int i = 0 ; i < _n; i++) d[size + i] = v[i];
@@ -69,14 +95,14 @@ struct lazy_segtree {
6995 for (int i = 1 ; i <= log; i++) update (p >> i);
7096 }
7197
72- S get (int p) const {
98+ S get (int p) {
7399 assert (0 <= p && p < _n);
74100 p += size;
75101 for (int i = log; i >= 1 ; i--) push (p >> i);
76102 return d[p];
77103 }
78104
79- S prod (int l, int r) const {
105+ S prod (int l, int r) {
80106 assert (0 <= l && l <= r && r <= _n);
81107 if (l == r) return e ();
82108
@@ -99,7 +125,7 @@ struct lazy_segtree {
99125 return op (sml, smr);
100126 }
101127
102- S all_prod () const { return d[1 ]; }
128+ S all_prod () { return d[1 ]; }
103129
104130 void apply (int p, F f) {
105131 assert (0 <= p && p < _n);
@@ -138,10 +164,10 @@ struct lazy_segtree {
138164 }
139165 }
140166
141- template <bool (*g)(S)> int max_right (int l) const {
167+ template <bool (*g)(S)> int max_right (int l) {
142168 return max_right (l, [](S x) { return g (x); });
143169 }
144- template <class G > int max_right (int l, G g) const {
170+ template <class G > int max_right (int l, G g) {
145171 assert (0 <= l && l <= _n);
146172 assert (g (e ()));
147173 if (l == _n) return _n;
@@ -167,10 +193,10 @@ struct lazy_segtree {
167193 return _n;
168194 }
169195
170- template <bool (*g)(S)> int min_left (int r) const {
196+ template <bool (*g)(S)> int min_left (int r) {
171197 return min_left (r, [](S x) { return g (x); });
172198 }
173- template <class G > int min_left (int r, G g) const {
199+ template <class G > int min_left (int r, G g) {
174200 assert (0 <= r && r <= _n);
175201 assert (g (e ()));
176202 if (r == 0 ) return 0 ;
@@ -198,23 +224,23 @@ struct lazy_segtree {
198224
199225protected:
200226 int _n, size, log;
201- mutable std::vector<S> d;
202- mutable std::vector<F> lz;
227+ std::vector<S> d;
228+ std::vector<F> lz;
203229
204- void update (int k) const { d[k] = op (d[2 * k], d[2 * k + 1 ]); }
205- virtual void all_apply (int k, F f) const {
230+ void update (int k) { d[k] = op (d[2 * k], d[2 * k + 1 ]); }
231+ virtual void all_apply (int k, F f) {
206232 d[k] = mapping (f, d[k]);
207233 if (k < size) lz[k] = composition (f, lz[k]);
208234 }
209- void push (int k) const {
235+ void push (int k) {
210236 all_apply (2 * k, lz[k]);
211237 all_apply (2 * k + 1 , lz[k]);
212238 lz[k] = id ();
213239 }
214240};
215241} // namespace atcoder
216242#endif // ATCODER_LAZYSEGTREE_HPP
217- // Reference: https://atcoder.github.io/ac-library/document_ja/lazysegtree.html
243+ // Reference: https://atcoder.github.io/ac-library/production/ document_ja/lazysegtree.html
218244// https://betrue12.hateblo.jp/entry/2020/09/22/194541
219245// https://betrue12.hateblo.jp/entry/2020/09/23/005940
220246/*
0 commit comments