@@ -8,29 +8,31 @@ pub struct DynamicArqNode<T: ArqSpec> {
8
8
down : ( usize , usize ) ,
9
9
}
10
10
11
- // TODO: can this be replaced by a #[derive(Clone)]?
11
+ // TODO: in a future Rust version, this might be replaced by a #[derive(Clone)]
12
12
impl < T : ArqSpec > Clone for DynamicArqNode < T > {
13
13
fn clone ( & self ) -> Self {
14
14
Self {
15
- val : T :: op ( & T :: identity ( ) , & self . val ) ,
15
+ val : self . val . clone ( ) ,
16
16
app : self . app . clone ( ) ,
17
17
down : self . down ,
18
18
}
19
19
}
20
20
}
21
21
22
- impl < T : ArqSpec > DynamicArqNode < T > {
23
- pub fn new ( val : T :: M ) -> Self {
22
+ impl < T : ArqSpec > Default for DynamicArqNode < T > {
23
+ fn default ( ) -> Self {
24
24
Self {
25
- val,
25
+ val : T :: identity ( ) ,
26
26
app : None ,
27
27
down : ( usize:: max_value ( ) , usize:: max_value ( ) ) ,
28
28
}
29
29
}
30
+ }
30
31
31
- fn apply ( & mut self , f : & T :: F , is_leaf : bool ) {
32
+ impl < T : ArqSpec > DynamicArqNode < T > {
33
+ fn apply ( & mut self , f : & T :: F , size : i64 ) {
32
34
self . val = T :: apply ( f, & self . val ) ;
33
- if !is_leaf {
35
+ if size > 1 {
34
36
let h = match self . app {
35
37
Some ( ref g) => T :: compose ( f, g) ,
36
38
None => f. clone ( ) ,
@@ -40,87 +42,69 @@ impl<T: ArqSpec> DynamicArqNode<T> {
40
42
}
41
43
}
42
44
43
- pub type ArqView = ( usize , i64 , i64 ) ;
45
+ pub type ArqView = ( usize , i64 ) ;
44
46
45
47
/// A dynamic, and optionally persistent, associative range query data structure.
46
48
pub struct DynamicArq < T : ArqSpec > {
47
49
nodes : Vec < DynamicArqNode < T > > ,
48
50
is_persistent : bool ,
49
- initializer : Box < dyn Fn ( i64 , i64 ) -> T :: M > ,
50
51
}
51
52
52
53
impl < T : ArqSpec > DynamicArq < T > {
53
54
/// Initializes the data structure without creating any nodes.
54
- /// The initializer f must satisfy: f(l, r) = T::op(f(l, m), f(m+1, r))
55
- pub fn new ( is_persistent : bool , initializer : Box < dyn Fn ( i64 , i64 ) -> T :: M > ) -> Self {
55
+ pub fn new ( is_persistent : bool ) -> Self {
56
56
Self {
57
57
nodes : vec ! [ ] ,
58
58
is_persistent,
59
- initializer,
60
59
}
61
60
}
62
61
63
- /// Initializes the data structure without creating any nodes.
64
- pub fn new_with_identity ( is_persistent : bool ) -> Self {
65
- let initializer = Box :: new ( |_, _| T :: identity ( ) ) ;
66
- Self :: new ( is_persistent, initializer)
67
- }
68
-
69
- /// Lazily builds a tree over the range [l_bound, r_bound].
70
- pub fn build_using_initializer ( & mut self , l_bound : i64 , r_bound : i64 ) -> ArqView {
71
- let view = ( self . nodes . len ( ) , l_bound, r_bound) ;
72
- let val = ( self . initializer ) ( l_bound, r_bound) ;
73
- self . nodes . push ( DynamicArqNode :: new ( val) ) ;
74
- view
62
+ /// Lazily builds a tree initialized to the identity.
63
+ pub fn build_from_identity ( & mut self , size : i64 ) -> ArqView {
64
+ self . nodes . push ( DynamicArqNode :: default ( ) ) ;
65
+ ( self . nodes . len ( ) - 1 , size)
75
66
}
76
67
77
68
/// Builds a tree whose leaves are set to a given non-empty slice.
78
69
pub fn build_from_slice ( & mut self , init_val : & [ T :: M ] ) -> ArqView {
79
70
if init_val. len ( ) == 1 {
80
- let view = ( self . nodes . len ( ) , 0 , 0 ) ;
81
- let val = T :: op ( & T :: identity ( ) , & init_val[ 0 ] ) ;
82
- self . nodes . push ( DynamicArqNode :: new ( val) ) ;
83
- return view;
71
+ let mut root = DynamicArqNode :: default ( ) ;
72
+ root. val = init_val[ 0 ] . clone ( ) ;
73
+ self . nodes . push ( root) ;
74
+ ( self . nodes . len ( ) - 1 , 1 )
75
+ } else {
76
+ let ls = init_val. len ( ) / 2 ;
77
+ let ( l_init, r_init) = init_val. split_at ( ls) ;
78
+ let l_view = self . build_from_slice ( l_init) ;
79
+ let r_view = self . build_from_slice ( r_init) ;
80
+ self . merge_equal_sized ( l_view, r_view)
84
81
}
85
- let m = ( init_val. len ( ) + 1 ) / 2 ;
86
- let ( l_init, r_init) = init_val. split_at ( m) ;
87
- let l_view = self . build_from_slice ( l_init) ;
88
- let r_view = self . build_from_slice ( r_init) ;
89
- self . merge_equal_sized ( l_view, r_view)
90
82
}
91
83
92
84
/// Merges two balanced subtrees into a single tree with a 0-indexed view.
93
- pub fn merge_equal_sized ( & mut self , l_view : ArqView , r_view : ArqView ) -> ArqView {
94
- let l_len = l_view. 2 - l_view. 1 + 1 ;
95
- let r_len = r_view. 2 - r_view. 1 + 1 ;
96
- assert ! ( l_len == r_len || l_len == r_len + 1 ) ;
97
-
98
- let view = ( self . nodes . len ( ) , 0 , l_len + r_len - 1 ) ;
99
- let root = DynamicArqNode {
100
- val : T :: identity ( ) ,
101
- app : None ,
102
- down : ( l_view. 0 , r_view. 0 ) ,
103
- } ;
85
+ pub fn merge_equal_sized ( & mut self , ( lp, ls) : ArqView , ( rp, rs) : ArqView ) -> ArqView {
86
+ assert ! ( ls == rs || ls + 1 == rs) ;
87
+ let p = self . nodes . len ( ) ;
88
+ let mut root = DynamicArqNode :: default ( ) ;
89
+ root. down = ( lp, rp) ;
104
90
self . nodes . push ( root) ;
105
- self . pull ( view . 0 ) ;
106
- view
91
+ self . pull ( p ) ;
92
+ ( p , ls + rs )
107
93
}
108
94
109
- pub fn push ( & mut self , ( p, l, r) : ArqView ) -> ( ArqView , ArqView ) {
110
- let m = ( l + r) / 2 ;
95
+ pub fn push ( & mut self , ( p, s) : ArqView ) -> ( ArqView , ArqView ) {
111
96
if self . nodes [ p] . down . 0 == usize:: max_value ( ) {
112
- let l_val = ( self . initializer ) ( l, m) ;
113
- let r_val = ( self . initializer ) ( m + 1 , r) ;
114
- self . nodes . push ( DynamicArqNode :: new ( l_val) ) ;
115
- self . nodes . push ( DynamicArqNode :: new ( r_val) ) ;
97
+ self . nodes . push ( DynamicArqNode :: default ( ) ) ;
98
+ self . nodes . push ( DynamicArqNode :: default ( ) ) ;
116
99
self . nodes [ p] . down = ( self . nodes . len ( ) - 2 , self . nodes . len ( ) - 1 )
117
100
} ;
118
101
let ( lp, rp) = self . nodes [ p] . down ;
102
+ let ls = s / 2 ;
119
103
if let Some ( ref f) = self . nodes [ p] . app . take ( ) {
120
- self . nodes [ lp] . apply ( f, l == m ) ;
121
- self . nodes [ rp] . apply ( f, m + 1 == r ) ;
104
+ self . nodes [ lp] . apply ( f, ls ) ;
105
+ self . nodes [ rp] . apply ( f, s - ls ) ;
122
106
}
123
- ( ( lp, l , m ) , ( rp, m + 1 , r ) )
107
+ ( ( lp, ls ) , ( rp, s - ls ) )
124
108
}
125
109
126
110
fn pull ( & mut self , p : usize ) {
@@ -130,48 +114,50 @@ impl<T: ArqSpec> DynamicArq<T> {
130
114
self . nodes [ p] . val = T :: op ( left_val, right_val) ;
131
115
}
132
116
133
- fn clone_node ( & mut self , p : usize ) -> usize {
117
+ fn clone_node ( & mut self , p_orig : usize ) -> usize {
134
118
if self . is_persistent {
135
- let node = self . nodes [ p ] . clone ( ) ;
119
+ let node = self . nodes [ p_orig ] . clone ( ) ;
136
120
self . nodes . push ( node) ;
137
121
self . nodes . len ( ) - 1
138
122
} else {
139
- p
123
+ p_orig
140
124
}
141
125
}
142
126
143
127
/// Applies the endomorphism f to all entries from l to r, inclusive.
144
128
/// If l == r, the updates are eager. Otherwise, they are lazy.
145
129
pub fn modify ( & mut self , view : ArqView , l : i64 , r : i64 , f : & T :: F ) -> ArqView {
146
- let ( p , cl , cr ) = view;
147
- if r < cl || cr < l {
130
+ let ( p_orig , s ) = view;
131
+ if r < 0 || s - 1 < l {
148
132
view
149
- } else if l <= cl && cr <= r /* && self.l == self.r forces eager */ {
150
- let p_clone = self . clone_node ( p ) ;
151
- self . nodes [ p_clone] . apply ( f, l == r ) ;
152
- ( p_clone, cl , cr )
133
+ } else if l <= 0 && s - 1 <= r {
134
+ let p_clone = self . clone_node ( p_orig ) ;
135
+ self . nodes [ p_clone] . apply ( f, s ) ;
136
+ ( p_clone, s )
153
137
} else {
154
138
let ( l_view, r_view) = self . push ( view) ;
155
- let p_clone = self . clone_node ( p) ;
139
+ let ls = l_view. 1 ;
140
+ let p_clone = self . clone_node ( p_orig) ;
156
141
let lp_clone = self . modify ( l_view, l, r, f) . 0 ;
157
- let rp_clone = self . modify ( r_view, l, r, f) . 0 ;
142
+ let rp_clone = self . modify ( r_view, l - ls , r - ls , f) . 0 ;
158
143
self . nodes [ p_clone] . down = ( lp_clone, rp_clone) ;
159
144
self . pull ( p_clone) ;
160
- ( p_clone, cl , cr )
145
+ ( p_clone, s )
161
146
}
162
147
}
163
148
164
149
/// Returns the aggregate range query on all entries from l to r, inclusive.
165
150
pub fn query ( & mut self , view : ArqView , l : i64 , r : i64 ) -> T :: M {
166
- let ( p, cl , cr ) = view;
167
- if r < cl || cr < l {
151
+ let ( p, s ) = view;
152
+ if r < 0 || s - 1 < l {
168
153
T :: identity ( )
169
- } else if l <= cl && cr <= r {
170
- T :: op ( & T :: identity ( ) , & self . nodes [ p] . val )
154
+ } else if l <= 0 && s - 1 <= r {
155
+ self . nodes [ p] . val . clone ( )
171
156
} else {
172
157
let ( l_view, r_view) = self . push ( view) ;
158
+ let ls = l_view. 1 ;
173
159
let l_agg = self . query ( l_view, l, r) ;
174
- let r_agg = self . query ( r_view, l, r) ;
160
+ let r_agg = self . query ( r_view, l - ls , r - ls ) ;
175
161
T :: op ( & l_agg, & r_agg)
176
162
}
177
163
}
@@ -180,16 +166,16 @@ impl<T: ArqSpec> DynamicArq<T> {
180
166
/// An example of binary search on the tree of a DynamicArq.
181
167
/// The tree may have any size, not necessarily a power of two.
182
168
pub fn first_negative ( arq : & mut DynamicArq < super :: specs:: AssignMin > , view : ArqView ) -> Option < i64 > {
183
- let ( p, cl , cr ) = view;
184
- if cl == cr {
185
- Some ( cl ) . filter ( |_| arq. nodes [ p] . val < 0 )
169
+ let ( p, s ) = view;
170
+ if s == 1 {
171
+ Some ( 0 ) . filter ( |_| arq. nodes [ p] . val < 0 )
186
172
} else {
187
173
let ( l_view, r_view) = arq. push ( view) ;
188
- let lp = l_view. 0 ;
174
+ let ( lp , ls ) = l_view;
189
175
if arq. nodes [ lp] . val < 0 {
190
176
first_negative ( arq, l_view)
191
177
} else {
192
- first_negative ( arq, r_view)
178
+ first_negative ( arq, r_view) . map ( |x| ls + x )
193
179
}
194
180
}
195
181
}
0 commit comments