@@ -168,10 +168,10 @@ impl<T: ArqSpec> DynamicArqNode<T> {
168
168
}
169
169
}
170
170
171
+ type ArqView = ( usize , i64 , i64 ) ;
172
+
171
173
/// A dynamic, and optionally persistent, associate range query data structure.
172
174
pub struct DynamicArq < T : ArqSpec > {
173
- l_bound : i64 ,
174
- r_bound : i64 ,
175
175
nodes : Vec < DynamicArqNode < T > > ,
176
176
is_persistent : bool ,
177
177
initializer : Box < dyn Fn ( i64 , i64 ) -> T :: M > ,
@@ -183,24 +183,24 @@ impl<T: ArqSpec> DynamicArq<T> {
183
183
r_bound : i64 ,
184
184
is_persistent : bool ,
185
185
initializer : Box < dyn Fn ( i64 , i64 ) -> T :: M > ,
186
- ) -> Self {
186
+ ) -> ( Self , ArqView ) {
187
187
let val = initializer ( l_bound, r_bound) ;
188
188
let nodes = vec ! [ DynamicArqNode :: new( val) ] ;
189
- Self {
190
- l_bound,
191
- r_bound,
189
+ let arq = Self {
192
190
nodes,
193
191
is_persistent,
194
192
initializer,
195
- }
193
+ } ;
194
+ let root_view = ( 0 , l_bound, r_bound) ;
195
+ ( arq, root_view)
196
196
}
197
197
198
- pub fn new_with_identity ( l_bound : i64 , r_bound : i64 , is_persistent : bool ) -> Self {
198
+ pub fn new_with_identity ( l_bound : i64 , r_bound : i64 , is_persistent : bool ) -> ( Self , ArqView ) {
199
199
let initializer = Box :: new ( |_, _| T :: identity ( ) ) ;
200
200
Self :: new ( l_bound, r_bound, is_persistent, initializer)
201
201
}
202
202
203
- fn push ( & mut self , p : usize , l : i64 , r : i64 ) -> ( usize , usize ) {
203
+ fn push ( & mut self , ( p , l, r) : ArqView ) -> ( ArqView , ArqView ) {
204
204
let m = ( l + r) / 2 ;
205
205
let ( lp, rp) = match self . nodes [ p] . down {
206
206
Some ( children) => children,
@@ -216,7 +216,7 @@ impl<T: ArqSpec> DynamicArq<T> {
216
216
self . nodes [ lp] . apply ( f, l == m) ;
217
217
self . nodes [ rp] . apply ( f, m + 1 == r) ;
218
218
}
219
- ( lp, rp )
219
+ ( ( lp, l , m ) , ( rp , m + 1 , r ) )
220
220
}
221
221
222
222
fn pull ( & mut self , p : usize ) {
@@ -236,49 +236,41 @@ impl<T: ArqSpec> DynamicArq<T> {
236
236
}
237
237
}
238
238
239
- fn m_helper ( & mut self , p : usize , l : i64 , r : i64 , f : & T :: F , cl : i64 , cr : i64 ) -> usize {
239
+ /// Applies the endomorphism f to all entries from l to r, inclusive.
240
+ /// If l == r, the updates are eager. Otherwise, they are lazy.
241
+ pub fn modify ( & mut self , view : ArqView , l : i64 , r : i64 , f : & T :: F ) -> ArqView {
242
+ let ( p, cl, cr) = view;
240
243
if r < cl || cr < l {
241
- p
244
+ view
242
245
} else if l <= cl && cr <= r /* && self.l == self.r forces eager */ {
243
246
let p_clone = self . clone_node ( p) ;
244
247
self . nodes [ p_clone] . apply ( f, l == r) ;
245
- p_clone
248
+ ( p_clone, cl , cr )
246
249
} else {
247
- let ( lp, rp) = self . push ( p, cl, cr) ;
248
- let cm = ( cl + cr) / 2 ;
250
+ let ( l_view, r_view) = self . push ( view) ;
249
251
let p_clone = self . clone_node ( p) ;
250
- let lp_clone = self . m_helper ( lp , l, r, f, cl , cm ) ;
251
- let rp_clone = self . m_helper ( rp , l, r, f, cm + 1 , cr ) ;
252
+ let lp_clone = self . modify ( l_view , l, r, f) . 0 ;
253
+ let rp_clone = self . modify ( r_view , l, r, f) . 0 ;
252
254
self . nodes [ p_clone] . down = Some ( ( lp_clone, rp_clone) ) ;
253
255
self . pull ( p_clone) ;
254
- p_clone
256
+ ( p_clone, cl , cr )
255
257
}
256
258
}
257
259
258
- fn q_helper ( & mut self , p : usize , l : i64 , r : i64 , cl : i64 , cr : i64 ) -> T :: M {
260
+ /// Returns the aggregate range query on all entries from l to r, inclusive.
261
+ pub fn query ( & mut self , view : ArqView , l : i64 , r : i64 ) -> T :: M {
262
+ let ( p, cl, cr) = view;
259
263
if r < cl || cr < l {
260
264
T :: identity ( )
261
265
} else if l <= cl && cr <= r {
262
266
T :: op ( & T :: identity ( ) , & self . nodes [ p] . val )
263
267
} else {
264
- let ( lp, rp) = self . push ( p, cl, cr) ;
265
- let cm = ( cl + cr) / 2 ;
266
- let l_agg = self . q_helper ( lp, l, r, cl, cm) ;
267
- let r_agg = self . q_helper ( rp, l, r, cm + 1 , cr) ;
268
+ let ( l_view, r_view) = self . push ( view) ;
269
+ let l_agg = self . query ( l_view, l, r) ;
270
+ let r_agg = self . query ( r_view, l, r) ;
268
271
T :: op ( & l_agg, & r_agg)
269
272
}
270
273
}
271
-
272
- /// Applies the endomorphism f to all entries from l to r, inclusive.
273
- /// If l == r, the updates are eager. Otherwise, they are lazy.
274
- pub fn modify ( & mut self , p : usize , l : i64 , r : i64 , f : & T :: F ) -> usize {
275
- self . m_helper ( p, l, r, f, self . l_bound , self . r_bound )
276
- }
277
-
278
- /// Returns the aggregate range query on all entries from l to r, inclusive.
279
- pub fn query ( & mut self , p : usize , l : i64 , r : i64 ) -> T :: M {
280
- self . q_helper ( p, l, r, self . l_bound , self . r_bound )
281
- }
282
274
}
283
275
284
276
pub trait ArqSpec {
@@ -351,18 +343,19 @@ pub fn first_negative_static(arq: &mut StaticArq<AssignMin>) -> i32 {
351
343
352
344
/// An example of binary search on the tree of a DynamicArq.
353
345
/// The tree may have any size, not necessarily a power of two.
354
- pub fn first_negative_dynamic ( arq : & mut DynamicArq < AssignMin > , p : usize , cl : i64 , cr : i64 ) -> i64 {
346
+ pub fn first_negative_dynamic ( arq : & mut DynamicArq < AssignMin > , view : ArqView ) -> i64 {
347
+ let ( p, cl, cr) = view;
355
348
if arq. nodes [ p] . val >= 0 {
356
349
-1
357
350
} else if cl == cr {
358
351
cl
359
352
} else {
360
- let ( lp , rp ) = arq. push ( p , cl , cr ) ;
361
- let cm = ( cl + cr ) / 2 ;
353
+ let ( l_view , r_view ) = arq. push ( view ) ;
354
+ let lp = l_view . 0 ;
362
355
if arq. nodes [ lp] . val < 0 {
363
- first_negative_dynamic ( arq, lp , cl , cm )
356
+ first_negative_dynamic ( arq, l_view )
364
357
} else {
365
- first_negative_dynamic ( arq, rp , cm + 1 , cr )
358
+ first_negative_dynamic ( arq, r_view )
366
359
}
367
360
}
368
361
}
@@ -554,31 +547,31 @@ mod test {
554
547
#[ test]
555
548
fn test_dynamic_rmq ( ) {
556
549
let initializer = Box :: new ( |_, _| 0 ) ;
557
- let mut arq = DynamicArq :: < AssignMin > :: new ( 0 , 9 , false , initializer) ;
550
+ let ( mut arq, view ) = DynamicArq :: < AssignMin > :: new ( 0 , 9 , false , initializer) ;
558
551
559
- assert_eq ! ( arq. query( 0 , 0 , 9 ) , 0 ) ;
552
+ assert_eq ! ( arq. query( view , 0 , 9 ) , 0 ) ;
560
553
561
- arq. modify ( 0 , 2 , 4 , & -5 ) ;
562
- arq. modify ( 0 , 5 , 7 , & -3 ) ;
563
- arq. modify ( 0 , 1 , 6 , & 1 ) ;
554
+ arq. modify ( view , 2 , 4 , & -5 ) ;
555
+ arq. modify ( view , 5 , 7 , & -3 ) ;
556
+ arq. modify ( view , 1 , 6 , & 1 ) ;
564
557
565
- assert_eq ! ( arq. query( 0 , 0 , 9 ) , -3 ) ;
558
+ assert_eq ! ( arq. query( view , 0 , 9 ) , -3 ) ;
566
559
}
567
560
568
561
#[ test]
569
562
fn test_persistent_rmq ( ) {
570
563
let initializer = Box :: new ( |_, _| 0 ) ;
571
- let mut arq = DynamicArq :: < AssignMin > :: new ( 0 , 9 , true , initializer) ;
564
+ let ( mut arq, mut view ) = DynamicArq :: < AssignMin > :: new ( 0 , 9 , true , initializer) ;
572
565
573
- let mut p = 0 ;
574
- p = arq. modify ( p , 2 , 4 , & -5 ) ;
575
- let snapshot = p ;
576
- p = arq. modify ( p , 5 , 7 , & -3 ) ;
577
- p = arq. modify ( p , 1 , 6 , & 1 ) ;
566
+ let at_init = view ;
567
+ view = arq. modify ( view , 2 , 4 , & -5 ) ;
568
+ let snapshot = view ;
569
+ view = arq. modify ( view , 5 , 7 , & -3 ) ;
570
+ view = arq. modify ( view , 1 , 6 , & 1 ) ;
578
571
579
- assert_eq ! ( arq. query( 0 , 0 , 9 ) , 0 ) ;
572
+ assert_eq ! ( arq. query( at_init , 0 , 9 ) , 0 ) ;
580
573
assert_eq ! ( arq. query( snapshot, 0 , 9 ) , -5 ) ;
581
- assert_eq ! ( arq. query( p , 0 , 9 ) , -3 ) ;
574
+ assert_eq ! ( arq. query( view , 0 , 9 ) , -3 ) ;
582
575
}
583
576
584
577
#[ test]
@@ -597,15 +590,15 @@ mod test {
597
590
#[ test]
598
591
fn test_dynamic_range_sum ( ) {
599
592
let initializer = Box :: new ( |l, r| ( 0 , 1 + r - l) ) ;
600
- let mut arq = DynamicArq :: < AssignSum > :: new ( 0 , 9 , false , initializer) ;
593
+ let ( mut arq, view ) = DynamicArq :: < AssignSum > :: new ( 0 , 9 , false , initializer) ;
601
594
602
- assert_eq ! ( arq. query( 0 , 0 , 9 ) , ( 0 , 10 ) ) ;
595
+ assert_eq ! ( arq. query( view , 0 , 9 ) , ( 0 , 10 ) ) ;
603
596
604
- arq. modify ( 0 , 1 , 3 , & 10 ) ;
605
- arq. modify ( 0 , 3 , 5 , & 1 ) ;
597
+ arq. modify ( view , 1 , 3 , & 10 ) ;
598
+ arq. modify ( view , 3 , 5 , & 1 ) ;
606
599
607
- assert_eq ! ( arq. query( 0 , 0 , 9 ) , ( 23 , 10 ) ) ;
608
- assert_eq ! ( arq. query( 0 , 10 , 4 ) , ( 0 , 0 ) ) ;
600
+ assert_eq ! ( arq. query( view , 0 , 9 ) , ( 23 , 10 ) ) ;
601
+ assert_eq ! ( arq. query( view , 10 , 4 ) , ( 0 , 0 ) ) ;
609
602
}
610
603
611
604
#[ test]
@@ -621,13 +614,13 @@ mod test {
621
614
622
615
#[ test]
623
616
fn test_dynamic_supply_demand ( ) {
624
- let mut arq = DynamicArq :: < SupplyDemand > :: new_with_identity ( 0 , 9 , false ) ;
617
+ let ( mut arq, view ) = DynamicArq :: < SupplyDemand > :: new_with_identity ( 0 , 9 , false ) ;
625
618
626
- arq. modify ( 0 , 1 , 1 , & ( 25 , 100 ) ) ;
627
- arq. modify ( 0 , 3 , 3 , & ( 100 , 30 ) ) ;
628
- arq. modify ( 0 , 9 , 9 , & ( 0 , 20 ) ) ;
619
+ arq. modify ( view , 1 , 1 , & ( 25 , 100 ) ) ;
620
+ arq. modify ( view , 3 , 3 , & ( 100 , 30 ) ) ;
621
+ arq. modify ( view , 9 , 9 , & ( 0 , 20 ) ) ;
629
622
630
- assert_eq ! ( arq. query( 0 , 0 , 9 ) , ( 125 , 150 , 75 ) ) ;
623
+ assert_eq ! ( arq. query( view , 0 , 9 ) , ( 125 , 150 , 75 ) ) ;
631
624
}
632
625
633
626
#[ test]
@@ -646,14 +639,17 @@ mod test {
646
639
#[ test]
647
640
fn test_dynamic_binary_search_rmq ( ) {
648
641
let initializer = Box :: new ( |_, r| 2 - r) ;
649
- let ( l_bound, r_bound) = ( 0 , 7 ) ;
650
- let mut arq = DynamicArq :: < AssignMin > :: new ( l_bound, r_bound, false , initializer) ;
651
- let pos = first_negative_dynamic ( & mut arq, 0 , l_bound , r_bound ) ;
642
+ let ( l_bound, r_bound) = ( 0 , 1_000_000_000_000_000_000 ) ;
643
+ let ( mut arq, view ) = DynamicArq :: < AssignMin > :: new ( l_bound, r_bound, false , initializer) ;
644
+ let pos = first_negative_dynamic ( & mut arq, view ) ;
652
645
653
- arq. modify ( 0 , 2 , 7 , & 0 ) ;
654
- let pos_zeros = first_negative_dynamic ( & mut arq, 0 , l_bound, r_bound) ;
646
+ arq. modify ( view, 2 , r_bound - 1 , & 0 ) ;
647
+ let pos_mostly_zeros = first_negative_dynamic ( & mut arq, view) ;
648
+ arq. modify ( view, 2 , r_bound, & 0 ) ;
649
+ let pos_zeros = first_negative_dynamic ( & mut arq, view) ;
655
650
656
651
assert_eq ! ( pos, 3 ) ;
652
+ assert_eq ! ( pos_mostly_zeros, r_bound) ;
657
653
assert_eq ! ( pos_zeros, -1 ) ;
658
654
}
659
655
0 commit comments