1
1
use crate :: internal_bit:: ceil_pow2;
2
- use crate :: internal_type_traits:: Integral ;
3
- use std:: cmp:: max;
2
+ use crate :: internal_type_traits:: { BoundedAbove , BoundedBelow , One , Zero } ;
3
+ use std:: cmp:: { max, min} ;
4
+ use std:: convert:: Infallible ;
4
5
use std:: marker:: PhantomData ;
6
+ use std:: ops:: { Add , Mul } ;
5
7
6
8
// TODO Should I split monoid-related traits to another module?
7
9
pub trait Monoid {
8
10
type S : Clone ;
9
11
fn identity ( ) -> Self :: S ;
10
- fn binary_operation ( a : Self :: S , b : Self :: S ) -> Self :: S ;
12
+ fn binary_operation ( a : & Self :: S , b : & Self :: S ) -> Self :: S ;
11
13
}
12
14
13
- pub struct Max < S > ( PhantomData < fn ( ) -> S > ) ;
14
- // TODO We should not restrict to integral
15
+ pub struct Max < S > ( Infallible , PhantomData < fn ( ) -> S > ) ;
15
16
impl < S > Monoid for Max < S >
16
17
where
17
- S : Integral ,
18
+ S : Copy + Ord + BoundedBelow ,
18
19
{
19
20
type S = S ;
20
-
21
21
fn identity ( ) -> Self :: S {
22
22
S :: min_value ( )
23
23
}
24
+ fn binary_operation ( a : & Self :: S , b : & Self :: S ) -> Self :: S {
25
+ max ( * a, * b)
26
+ }
27
+ }
28
+
29
+ pub struct Min < S > ( Infallible , PhantomData < fn ( ) -> S > ) ;
30
+ impl < S > Monoid for Min < S >
31
+ where
32
+ S : Copy + Ord + BoundedAbove ,
33
+ {
34
+ type S = S ;
35
+ fn identity ( ) -> Self :: S {
36
+ S :: max_value ( )
37
+ }
38
+ fn binary_operation ( a : & Self :: S , b : & Self :: S ) -> Self :: S {
39
+ min ( * a, * b)
40
+ }
41
+ }
42
+
43
+ pub struct Sum < S > ( Infallible , PhantomData < fn ( ) -> S > ) ;
44
+ impl < S > Monoid for Sum < S >
45
+ where
46
+ S : Copy + Add < Output = S > + Zero ,
47
+ {
48
+ type S = S ;
49
+ fn identity ( ) -> Self :: S {
50
+ S :: zero ( )
51
+ }
52
+ fn binary_operation ( a : & Self :: S , b : & Self :: S ) -> Self :: S {
53
+ * a + * b
54
+ }
55
+ }
24
56
25
- fn binary_operation ( a : Self :: S , b : Self :: S ) -> Self :: S {
26
- max ( a, b)
57
+ pub struct Product < S > ( Infallible , PhantomData < fn ( ) -> S > ) ;
58
+ impl < S > Monoid for Product < S >
59
+ where
60
+ S : Copy + Mul < Output = S > + One ,
61
+ {
62
+ type S = S ;
63
+ fn identity ( ) -> Self :: S {
64
+ S :: one ( )
65
+ }
66
+ fn binary_operation ( a : & Self :: S , b : & Self :: S ) -> Self :: S {
67
+ * a * * b
27
68
}
28
69
}
29
70
@@ -75,18 +116,18 @@ impl<M: Monoid> Segtree<M> {
75
116
76
117
while l < r {
77
118
if l & 1 != 0 {
78
- sml = M :: binary_operation ( sml, self . d [ l] . clone ( ) ) ;
119
+ sml = M :: binary_operation ( & sml, & self . d [ l] ) ;
79
120
l += 1 ;
80
121
}
81
122
if r & 1 != 0 {
82
123
r -= 1 ;
83
- smr = M :: binary_operation ( self . d [ r] . clone ( ) , smr) ;
124
+ smr = M :: binary_operation ( & self . d [ r] , & smr) ;
84
125
}
85
126
l >>= 1 ;
86
127
r >>= 1 ;
87
128
}
88
129
89
- M :: binary_operation ( sml, smr)
130
+ M :: binary_operation ( & sml, & smr)
90
131
}
91
132
92
133
pub fn all_prod ( & self ) -> M :: S {
@@ -109,18 +150,18 @@ impl<M: Monoid> Segtree<M> {
109
150
while l % 2 == 0 {
110
151
l >>= 1 ;
111
152
}
112
- if !f ( M :: binary_operation ( sm . clone ( ) , self . d [ l] . clone ( ) ) ) {
153
+ if !f ( M :: binary_operation ( & sm , & self . d [ l] ) ) {
113
154
while l < self . size {
114
155
l *= 2 ;
115
- let res = M :: binary_operation ( sm . clone ( ) , self . d [ l] . clone ( ) ) ;
156
+ let res = M :: binary_operation ( & sm , & self . d [ l] ) ;
116
157
if f ( res. clone ( ) ) {
117
158
sm = res;
118
159
l += 1 ;
119
160
}
120
161
}
121
162
return l - self . size ;
122
163
}
123
- sm = M :: binary_operation ( sm . clone ( ) , self . d [ l] . clone ( ) ) ;
164
+ sm = M :: binary_operation ( & sm , & self . d [ l] ) ;
124
165
l += 1 ;
125
166
// while
126
167
{
@@ -148,18 +189,18 @@ impl<M: Monoid> Segtree<M> {
148
189
while r > 1 && r % 2 == 1 {
149
190
r >>= 1 ;
150
191
}
151
- if !f ( M :: binary_operation ( self . d [ r] . clone ( ) , sm . clone ( ) ) ) {
192
+ if !f ( M :: binary_operation ( & self . d [ r] , & sm ) ) {
152
193
while r < self . size {
153
194
r = 2 * r + 1 ;
154
- let res = M :: binary_operation ( self . d [ r] . clone ( ) , sm . clone ( ) ) ;
195
+ let res = M :: binary_operation ( & self . d [ r] , & sm ) ;
155
196
if f ( res. clone ( ) ) {
156
197
sm = res;
157
198
r -= 1 ;
158
199
}
159
200
}
160
201
return r + 1 - self . size ;
161
202
}
162
- sm = M :: binary_operation ( self . d [ r] . clone ( ) , sm . clone ( ) ) ;
203
+ sm = M :: binary_operation ( & self . d [ r] , & sm ) ;
163
204
// while
164
205
{
165
206
let r = r as isize ;
@@ -170,7 +211,7 @@ impl<M: Monoid> Segtree<M> {
170
211
}
171
212
172
213
fn update ( & mut self , k : usize ) {
173
- self . d [ k] = M :: binary_operation ( self . d [ 2 * k] . clone ( ) , self . d [ 2 * k + 1 ] . clone ( ) ) ;
214
+ self . d [ k] = M :: binary_operation ( & self . d [ 2 * k] , & self . d [ 2 * k + 1 ] ) ;
174
215
}
175
216
}
176
217
0 commit comments