pub struct LazySegTree<Spec: LazySegTreeSpec> { /* private fields */ }Expand description
Generic lazy segment tree.
The tree stores aggregates of type Spec::T and lazy tags of Spec::U.
Supports efficient range queries and range updates in O(log n) time.
§Type Parameters
Spec- A type implementingLazySegTreeSpecthat defines the operations
Implementations§
Source§impl<Spec: LazySegTreeSpec> LazySegTree<Spec>
impl<Spec: LazySegTreeSpec> LazySegTree<Spec>
Sourcepub fn new(size: usize) -> Self
pub fn new(size: usize) -> Self
Create a new tree of size elements, all initialized to Spec::ID.
The internal tree size (max_size) will be the next power of two
greater than or equal to size for efficient tree operations.
§Time Complexity
O(n) where n is the next power of two >= size.
§Examples
use array_range_query::{LazySegTree, LazySegTreeSpec};
let tree = LazySegTree::<RangeAddSum>::new(100);
assert_eq!(tree.query(..), 0); // All elements start as identity (0)Sourcepub fn from_vec(values: &[Spec::T]) -> Self
pub fn from_vec(values: &[Spec::T]) -> Self
Build a tree from a slice of initial values.
The tree is constructed bottom-up in O(n) time, which is more efficient than creating an empty tree and updating each element individually.
§Time Complexity
O(n) where n is the length of values.
§Examples
use array_range_query::{LazySegTree, LazySegTreeSpec};
let values = vec![1, 2, 3, 4, 5];
let tree = LazySegTree::<RangeAddSum>::from_vec(&values);
assert_eq!(tree.query(..), 15); // Sum of all elementsExamples found in repository?
129fn custom_lazy_example() {
130 println!("4. Custom LazySegTree for Range Add + Range Sum");
131 println!("----------------------------------------------");
132
133 // Define a spec for range add operations with sum queries
134 struct RangeAddSum;
135
136 impl LazySegTreeSpec for RangeAddSum {
137 type T = i64; // Data type (stores sums)
138 type U = i64; // Update type (add values)
139 const ID: Self::T = 0;
140
141 // Combine two sum values
142 fn op_on_data(d1: &mut Self::T, d2: &Self::T) {
143 *d1 += *d2;
144 }
145
146 // Compose two add operations
147 fn op_on_update(u1: &mut Self::U, u2: &Self::U) {
148 *u1 += *u2;
149 }
150
151 // Apply add operation to sum (multiply by range size)
152 fn op_update_on_data(u: &Self::U, d: &mut Self::T, size: usize) {
153 *d += u * (size as i64);
154 }
155 }
156
157 let values = vec![1i64, 2, 3, 4, 5];
158 let mut lazy_tree = LazySegTree::<RangeAddSum>::from_vec(&values);
159
160 println!("Initial values: {:?}", values);
161 println!("Initial sum [1, 4): {}", lazy_tree.query(1..4)); // 2 + 3 + 4 = 9
162 println!("Initial sum [0, 5): {}", lazy_tree.query(..)); // 15
163
164 // Add 10 to all elements in range [1, 4)
165 lazy_tree.update(1..4, 10);
166 println!("\nAfter adding 10 to range [1, 4):");
167 println!("Sum [1, 4): {}", lazy_tree.query(1..4)); // (2+10) + (3+10) + (4+10) = 39
168 println!("Sum [0, 5): {}", lazy_tree.query(..)); // 1 + 12 + 13 + 14 + 5 = 45
169
170 // Add 5 to range [0, 2)
171 lazy_tree.update(..2, 5);
172 println!("\nAfter adding 5 to range [0, 2):");
173 println!("Sum [0, 2): {}", lazy_tree.query(..2)); // (1+5) + (12+5) = 23
174 println!("Sum [0, 5): {}", lazy_tree.query(..)); // 6 + 17 + 13 + 14 + 5 = 55
175 println!();
176}
177
178/// Example 5: Using LazySegTree helper types
179fn lazy_helper_example() {
180 println!("5. LazySegTree Helper Types");
181 println!("--------------------------");
182
183 // Range add + range sum
184 let values = vec![2i32, 4, 6, 8, 10];
185 let mut sum_tree = LazySegTreeAddSum::<i32>::from_vec(&values);
186
187 println!("Initial values: {:?}", values);
188 println!("Sum [0, 5): {}", sum_tree.query(..)); // 30
189 println!("Sum [1, 4): {}", sum_tree.query(1..4)); // 4 + 6 + 8 = 18
190
191 // Add 3 to range [1, 4)
192 sum_tree.update(1..4, 3);
193 println!("\nAfter adding 3 to range [1, 4):");
194 println!("Sum [0, 5): {}", sum_tree.query(..)); // 2 + 7 + 9 + 11 + 10 = 39
195 println!("Sum [1, 4): {}", sum_tree.query(1..4)); // 7 + 9 + 11 = 27
196
197 // Add -2 to range [0, 3)
198 sum_tree.update(..3, -2);
199 println!("\nAfter subtracting 2 from range [0, 3):");
200 println!("Sum [0, 5): {}", sum_tree.query(..)); // 0 + 5 + 7 + 11 + 10 = 33
201 println!("Sum [0, 3): {}", sum_tree.query(..3)); // 0 + 5 + 7 = 12
202
203 // Range add + range min
204 let min_values = vec![5, 2, 8, 1, 9, 3];
205 let mut min_tree = LazySegTreeAddMin::<i32>::from_vec(&min_values);
206 println!("\nInitial min values: {:?}", min_values);
207 println!("Min [0, 6): {}", min_tree.query(..)); // 1
208 min_tree.update(1..4, 2);
209 println!(
210 "After adding 2 to [1, 4): Min [0, 6): {}",
211 min_tree.query(..)
212 ); // min(5, 4, 10, 3, 9, 3) = 3
213
214 // Range assignment (replace) + range sum
215 let rep_values = vec![1, 2, 3, 4, 5];
216 let mut rep_tree = LazySegTreeReplaceSum::<i32>::from_vec(&rep_values);
217 println!("\nInitial replace values: {:?}", rep_values);
218 println!("Sum [0, 5): {}", rep_tree.query(..)); // 15
219 rep_tree.update(1..4, 10); // Replace [1, 4) with 10
220 println!(
221 "After replacing [1, 4) with 10: Sum [0, 5): {}",
222 rep_tree.query(..)
223 ); // 1 + 10 + 10 + 10 + 5 = 36
224 println!();
225}
226
227/// Example 6: Advanced lazy operations with overlapping updates
228fn advanced_lazy_example() {
229 println!("6. Advanced Lazy Operations");
230 println!("--------------------------");
231
232 let values = vec![1i32, 1, 1, 1, 1, 1, 1, 1]; // 8 ones
233 let mut tree = LazySegTreeAddSum::<i32>::from_vec(&values);
234
235 println!("Initial: 8 ones, sum = {}", tree.query(..));
236
237 // Perform overlapping updates
238 tree.update(..4, 2); // Add 2 to first half
239 tree.update(2..6, 3); // Add 3 to middle section (overlaps)
240 tree.update(4.., 1); // Add 1 to second half
241
242 println!("After overlapping updates:");
243 println!("Range [0, 2): sum = {}", tree.query(..2)); // (1+2) + (1+2) = 6
244 println!("Range [2, 4): sum = {}", tree.query(2..4)); // (1+2+3) + (1+2+3) = 12
245 println!("Range [4, 6): sum = {}", tree.query(4..6)); // (1+3+1) + (1+3+1) = 10
246 println!("Range [6, 8): sum = {}", tree.query(6..)); // (1+1) + (1+1) = 4
247 println!("Total sum: {}", tree.query(..)); // 6 + 12 + 10 + 4 = 32
248
249 // Verify by querying individual ranges
250 let mut total = 0;
251 for i in 0..4 {
252 let range_sum = tree.query(i * 2..(i + 1) * 2);
253 total += range_sum;
254 println!(" Range [{}, {}): {}", i * 2, (i + 1) * 2, range_sum);
255 }
256 println!("Sum verification: {}", total);
257 println!();
258}Sourcepub fn query<R: RangeBounds<usize>>(&self, range: R) -> Spec::T
pub fn query<R: RangeBounds<usize>>(&self, range: R) -> Spec::T
Query the range specified by range.
Returns the aggregate value over the specified range using the op_on_data operation.
The range can be any type that implements RangeBounds<usize>, such as
a..b, a..=b, ..b, a.., or ...
§Time Complexity
O(log n)
§Panics
Panics if the range is invalid (start > end) or out of bounds.
§Examples
use array_range_query::{LazySegTree, LazySegTreeSpec};
let tree = LazySegTree::<RangeAddSum>::from_vec(&[1, 2, 3, 4, 5]);
assert_eq!(tree.query(1..4), 9); // Sum of elements [2, 3, 4]
assert_eq!(tree.query(..), 15); // Sum of all elementsExamples found in repository?
129fn custom_lazy_example() {
130 println!("4. Custom LazySegTree for Range Add + Range Sum");
131 println!("----------------------------------------------");
132
133 // Define a spec for range add operations with sum queries
134 struct RangeAddSum;
135
136 impl LazySegTreeSpec for RangeAddSum {
137 type T = i64; // Data type (stores sums)
138 type U = i64; // Update type (add values)
139 const ID: Self::T = 0;
140
141 // Combine two sum values
142 fn op_on_data(d1: &mut Self::T, d2: &Self::T) {
143 *d1 += *d2;
144 }
145
146 // Compose two add operations
147 fn op_on_update(u1: &mut Self::U, u2: &Self::U) {
148 *u1 += *u2;
149 }
150
151 // Apply add operation to sum (multiply by range size)
152 fn op_update_on_data(u: &Self::U, d: &mut Self::T, size: usize) {
153 *d += u * (size as i64);
154 }
155 }
156
157 let values = vec![1i64, 2, 3, 4, 5];
158 let mut lazy_tree = LazySegTree::<RangeAddSum>::from_vec(&values);
159
160 println!("Initial values: {:?}", values);
161 println!("Initial sum [1, 4): {}", lazy_tree.query(1..4)); // 2 + 3 + 4 = 9
162 println!("Initial sum [0, 5): {}", lazy_tree.query(..)); // 15
163
164 // Add 10 to all elements in range [1, 4)
165 lazy_tree.update(1..4, 10);
166 println!("\nAfter adding 10 to range [1, 4):");
167 println!("Sum [1, 4): {}", lazy_tree.query(1..4)); // (2+10) + (3+10) + (4+10) = 39
168 println!("Sum [0, 5): {}", lazy_tree.query(..)); // 1 + 12 + 13 + 14 + 5 = 45
169
170 // Add 5 to range [0, 2)
171 lazy_tree.update(..2, 5);
172 println!("\nAfter adding 5 to range [0, 2):");
173 println!("Sum [0, 2): {}", lazy_tree.query(..2)); // (1+5) + (12+5) = 23
174 println!("Sum [0, 5): {}", lazy_tree.query(..)); // 6 + 17 + 13 + 14 + 5 = 55
175 println!();
176}
177
178/// Example 5: Using LazySegTree helper types
179fn lazy_helper_example() {
180 println!("5. LazySegTree Helper Types");
181 println!("--------------------------");
182
183 // Range add + range sum
184 let values = vec![2i32, 4, 6, 8, 10];
185 let mut sum_tree = LazySegTreeAddSum::<i32>::from_vec(&values);
186
187 println!("Initial values: {:?}", values);
188 println!("Sum [0, 5): {}", sum_tree.query(..)); // 30
189 println!("Sum [1, 4): {}", sum_tree.query(1..4)); // 4 + 6 + 8 = 18
190
191 // Add 3 to range [1, 4)
192 sum_tree.update(1..4, 3);
193 println!("\nAfter adding 3 to range [1, 4):");
194 println!("Sum [0, 5): {}", sum_tree.query(..)); // 2 + 7 + 9 + 11 + 10 = 39
195 println!("Sum [1, 4): {}", sum_tree.query(1..4)); // 7 + 9 + 11 = 27
196
197 // Add -2 to range [0, 3)
198 sum_tree.update(..3, -2);
199 println!("\nAfter subtracting 2 from range [0, 3):");
200 println!("Sum [0, 5): {}", sum_tree.query(..)); // 0 + 5 + 7 + 11 + 10 = 33
201 println!("Sum [0, 3): {}", sum_tree.query(..3)); // 0 + 5 + 7 = 12
202
203 // Range add + range min
204 let min_values = vec![5, 2, 8, 1, 9, 3];
205 let mut min_tree = LazySegTreeAddMin::<i32>::from_vec(&min_values);
206 println!("\nInitial min values: {:?}", min_values);
207 println!("Min [0, 6): {}", min_tree.query(..)); // 1
208 min_tree.update(1..4, 2);
209 println!(
210 "After adding 2 to [1, 4): Min [0, 6): {}",
211 min_tree.query(..)
212 ); // min(5, 4, 10, 3, 9, 3) = 3
213
214 // Range assignment (replace) + range sum
215 let rep_values = vec![1, 2, 3, 4, 5];
216 let mut rep_tree = LazySegTreeReplaceSum::<i32>::from_vec(&rep_values);
217 println!("\nInitial replace values: {:?}", rep_values);
218 println!("Sum [0, 5): {}", rep_tree.query(..)); // 15
219 rep_tree.update(1..4, 10); // Replace [1, 4) with 10
220 println!(
221 "After replacing [1, 4) with 10: Sum [0, 5): {}",
222 rep_tree.query(..)
223 ); // 1 + 10 + 10 + 10 + 5 = 36
224 println!();
225}
226
227/// Example 6: Advanced lazy operations with overlapping updates
228fn advanced_lazy_example() {
229 println!("6. Advanced Lazy Operations");
230 println!("--------------------------");
231
232 let values = vec![1i32, 1, 1, 1, 1, 1, 1, 1]; // 8 ones
233 let mut tree = LazySegTreeAddSum::<i32>::from_vec(&values);
234
235 println!("Initial: 8 ones, sum = {}", tree.query(..));
236
237 // Perform overlapping updates
238 tree.update(..4, 2); // Add 2 to first half
239 tree.update(2..6, 3); // Add 3 to middle section (overlaps)
240 tree.update(4.., 1); // Add 1 to second half
241
242 println!("After overlapping updates:");
243 println!("Range [0, 2): sum = {}", tree.query(..2)); // (1+2) + (1+2) = 6
244 println!("Range [2, 4): sum = {}", tree.query(2..4)); // (1+2+3) + (1+2+3) = 12
245 println!("Range [4, 6): sum = {}", tree.query(4..6)); // (1+3+1) + (1+3+1) = 10
246 println!("Range [6, 8): sum = {}", tree.query(6..)); // (1+1) + (1+1) = 4
247 println!("Total sum: {}", tree.query(..)); // 6 + 12 + 10 + 4 = 32
248
249 // Verify by querying individual ranges
250 let mut total = 0;
251 for i in 0..4 {
252 let range_sum = tree.query(i * 2..(i + 1) * 2);
253 total += range_sum;
254 println!(" Range [{}, {}): {}", i * 2, (i + 1) * 2, range_sum);
255 }
256 println!("Sum verification: {}", total);
257 println!();
258}Sourcepub fn update<R: RangeBounds<usize>>(&mut self, range: R, value: Spec::U)
pub fn update<R: RangeBounds<usize>>(&mut self, range: R, value: Spec::U)
Apply value lazily to the range specified by range.
Updates all elements in the specified range by applying the given update value.
The range can be any type that implements RangeBounds<usize>.
§Time Complexity
O(log n)
§Panics
Panics if the range is invalid (start > end) or out of bounds.
§Examples
use array_range_query::{LazySegTree, LazySegTreeSpec};
let mut tree = LazySegTree::<RangeAddSum>::from_vec(&[1, 2, 3, 4, 5]);
tree.update(1..4, 10); // Add 10 to elements at indices 1, 2, 3
assert_eq!(tree.query(..), 45); // 1 + 12 + 13 + 14 + 5Examples found in repository?
129fn custom_lazy_example() {
130 println!("4. Custom LazySegTree for Range Add + Range Sum");
131 println!("----------------------------------------------");
132
133 // Define a spec for range add operations with sum queries
134 struct RangeAddSum;
135
136 impl LazySegTreeSpec for RangeAddSum {
137 type T = i64; // Data type (stores sums)
138 type U = i64; // Update type (add values)
139 const ID: Self::T = 0;
140
141 // Combine two sum values
142 fn op_on_data(d1: &mut Self::T, d2: &Self::T) {
143 *d1 += *d2;
144 }
145
146 // Compose two add operations
147 fn op_on_update(u1: &mut Self::U, u2: &Self::U) {
148 *u1 += *u2;
149 }
150
151 // Apply add operation to sum (multiply by range size)
152 fn op_update_on_data(u: &Self::U, d: &mut Self::T, size: usize) {
153 *d += u * (size as i64);
154 }
155 }
156
157 let values = vec![1i64, 2, 3, 4, 5];
158 let mut lazy_tree = LazySegTree::<RangeAddSum>::from_vec(&values);
159
160 println!("Initial values: {:?}", values);
161 println!("Initial sum [1, 4): {}", lazy_tree.query(1..4)); // 2 + 3 + 4 = 9
162 println!("Initial sum [0, 5): {}", lazy_tree.query(..)); // 15
163
164 // Add 10 to all elements in range [1, 4)
165 lazy_tree.update(1..4, 10);
166 println!("\nAfter adding 10 to range [1, 4):");
167 println!("Sum [1, 4): {}", lazy_tree.query(1..4)); // (2+10) + (3+10) + (4+10) = 39
168 println!("Sum [0, 5): {}", lazy_tree.query(..)); // 1 + 12 + 13 + 14 + 5 = 45
169
170 // Add 5 to range [0, 2)
171 lazy_tree.update(..2, 5);
172 println!("\nAfter adding 5 to range [0, 2):");
173 println!("Sum [0, 2): {}", lazy_tree.query(..2)); // (1+5) + (12+5) = 23
174 println!("Sum [0, 5): {}", lazy_tree.query(..)); // 6 + 17 + 13 + 14 + 5 = 55
175 println!();
176}
177
178/// Example 5: Using LazySegTree helper types
179fn lazy_helper_example() {
180 println!("5. LazySegTree Helper Types");
181 println!("--------------------------");
182
183 // Range add + range sum
184 let values = vec![2i32, 4, 6, 8, 10];
185 let mut sum_tree = LazySegTreeAddSum::<i32>::from_vec(&values);
186
187 println!("Initial values: {:?}", values);
188 println!("Sum [0, 5): {}", sum_tree.query(..)); // 30
189 println!("Sum [1, 4): {}", sum_tree.query(1..4)); // 4 + 6 + 8 = 18
190
191 // Add 3 to range [1, 4)
192 sum_tree.update(1..4, 3);
193 println!("\nAfter adding 3 to range [1, 4):");
194 println!("Sum [0, 5): {}", sum_tree.query(..)); // 2 + 7 + 9 + 11 + 10 = 39
195 println!("Sum [1, 4): {}", sum_tree.query(1..4)); // 7 + 9 + 11 = 27
196
197 // Add -2 to range [0, 3)
198 sum_tree.update(..3, -2);
199 println!("\nAfter subtracting 2 from range [0, 3):");
200 println!("Sum [0, 5): {}", sum_tree.query(..)); // 0 + 5 + 7 + 11 + 10 = 33
201 println!("Sum [0, 3): {}", sum_tree.query(..3)); // 0 + 5 + 7 = 12
202
203 // Range add + range min
204 let min_values = vec![5, 2, 8, 1, 9, 3];
205 let mut min_tree = LazySegTreeAddMin::<i32>::from_vec(&min_values);
206 println!("\nInitial min values: {:?}", min_values);
207 println!("Min [0, 6): {}", min_tree.query(..)); // 1
208 min_tree.update(1..4, 2);
209 println!(
210 "After adding 2 to [1, 4): Min [0, 6): {}",
211 min_tree.query(..)
212 ); // min(5, 4, 10, 3, 9, 3) = 3
213
214 // Range assignment (replace) + range sum
215 let rep_values = vec![1, 2, 3, 4, 5];
216 let mut rep_tree = LazySegTreeReplaceSum::<i32>::from_vec(&rep_values);
217 println!("\nInitial replace values: {:?}", rep_values);
218 println!("Sum [0, 5): {}", rep_tree.query(..)); // 15
219 rep_tree.update(1..4, 10); // Replace [1, 4) with 10
220 println!(
221 "After replacing [1, 4) with 10: Sum [0, 5): {}",
222 rep_tree.query(..)
223 ); // 1 + 10 + 10 + 10 + 5 = 36
224 println!();
225}
226
227/// Example 6: Advanced lazy operations with overlapping updates
228fn advanced_lazy_example() {
229 println!("6. Advanced Lazy Operations");
230 println!("--------------------------");
231
232 let values = vec![1i32, 1, 1, 1, 1, 1, 1, 1]; // 8 ones
233 let mut tree = LazySegTreeAddSum::<i32>::from_vec(&values);
234
235 println!("Initial: 8 ones, sum = {}", tree.query(..));
236
237 // Perform overlapping updates
238 tree.update(..4, 2); // Add 2 to first half
239 tree.update(2..6, 3); // Add 3 to middle section (overlaps)
240 tree.update(4.., 1); // Add 1 to second half
241
242 println!("After overlapping updates:");
243 println!("Range [0, 2): sum = {}", tree.query(..2)); // (1+2) + (1+2) = 6
244 println!("Range [2, 4): sum = {}", tree.query(2..4)); // (1+2+3) + (1+2+3) = 12
245 println!("Range [4, 6): sum = {}", tree.query(4..6)); // (1+3+1) + (1+3+1) = 10
246 println!("Range [6, 8): sum = {}", tree.query(6..)); // (1+1) + (1+1) = 4
247 println!("Total sum: {}", tree.query(..)); // 6 + 12 + 10 + 4 = 32
248
249 // Verify by querying individual ranges
250 let mut total = 0;
251 for i in 0..4 {
252 let range_sum = tree.query(i * 2..(i + 1) * 2);
253 total += range_sum;
254 println!(" Range [{}, {}): {}", i * 2, (i + 1) * 2, range_sum);
255 }
256 println!("Sum verification: {}", total);
257 println!();
258}Trait Implementations§
Source§impl<Spec: Clone + LazySegTreeSpec> Clone for LazySegTree<Spec>
impl<Spec: Clone + LazySegTreeSpec> Clone for LazySegTree<Spec>
Source§fn clone(&self) -> LazySegTree<Spec>
fn clone(&self) -> LazySegTree<Spec>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more