@@ -3,7 +3,7 @@ use crate::internal_type_traits::{BoundedAbove, BoundedBelow, One, Zero};
33use std:: cmp:: { max, min} ;
44use std:: convert:: Infallible ;
55use std:: marker:: PhantomData ;
6- use std:: ops:: { Add , Mul } ;
6+ use std:: ops:: { Add , Bound , Mul , RangeBounds } ;
77
88// TODO Should I split monoid-related traits to another module?
99pub trait Monoid {
@@ -107,7 +107,27 @@ impl<M: Monoid> Segtree<M> {
107107 self . d [ p + self . size ] . clone ( )
108108 }
109109
110- pub fn prod ( & self , mut l : usize , mut r : usize ) -> M :: S {
110+ pub fn prod < R > ( & self , range : R ) -> M :: S
111+ where
112+ R : RangeBounds < usize > ,
113+ {
114+ // Trivial optimization
115+ if range. start_bound ( ) == Bound :: Unbounded && range. end_bound ( ) == Bound :: Unbounded {
116+ return self . all_prod ( ) ;
117+ }
118+
119+ let mut r = match range. end_bound ( ) {
120+ Bound :: Included ( r) => r + 1 ,
121+ Bound :: Excluded ( r) => * r,
122+ Bound :: Unbounded => self . n ,
123+ } ;
124+ let mut l = match range. start_bound ( ) {
125+ Bound :: Included ( l) => * l,
126+ Bound :: Excluded ( l) => l + 1 ,
127+ // TODO: There are another way of optimizing [0..r)
128+ Bound :: Unbounded => 0 ,
129+ } ;
130+
111131 assert ! ( l <= r && r <= self . n) ;
112132 let mut sml = M :: identity ( ) ;
113133 let mut smr = M :: identity ( ) ;
@@ -240,6 +260,7 @@ where
240260mod tests {
241261 use crate :: segtree:: Max ;
242262 use crate :: Segtree ;
263+ use std:: ops:: { Bound :: * , RangeBounds } ;
243264
244265 #[ test]
245266 fn test_max_segtree ( ) {
@@ -272,12 +293,20 @@ mod tests {
272293 for i in 0 ..n {
273294 assert_eq ! ( segtree. get( i) , base[ i] ) ;
274295 }
296+
297+ check ( base, segtree, ..) ;
275298 for i in 0 ..=n {
299+ check ( base, segtree, ..i) ;
300+ check ( base, segtree, i..) ;
301+ if i < n {
302+ check ( base, segtree, ..=i) ;
303+ }
276304 for j in i..=n {
277- assert_eq ! (
278- segtree. prod( i, j) ,
279- base[ i..j] . iter( ) . max( ) . copied( ) . unwrap_or( i32 :: min_value( ) )
280- ) ;
305+ check ( base, segtree, i..j) ;
306+ if j < n {
307+ check ( base, segtree, i..=j) ;
308+ check ( base, segtree, ( Excluded ( i) , Included ( j) ) ) ;
309+ }
281310 }
282311 }
283312 assert_eq ! (
@@ -312,4 +341,15 @@ mod tests {
312341 }
313342 }
314343 }
344+
345+ fn check ( base : & [ i32 ] , segtree : & Segtree < Max < i32 > > , range : impl RangeBounds < usize > ) {
346+ let expected = base
347+ . iter ( )
348+ . enumerate ( )
349+ . filter_map ( |( i, a) | Some ( a) . filter ( |_| range. contains ( & i) ) )
350+ . max ( )
351+ . copied ( )
352+ . unwrap_or ( i32:: min_value ( ) ) ;
353+ assert_eq ! ( segtree. prod( range) , expected) ;
354+ }
315355}
0 commit comments