LazySegTree

Struct LazySegTree 

Source
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. Public operations:

  • new(size) and from_vec(values) to construct,
  • query(&self, left, right) to query [left, right),
  • update(&mut self, left, right, value) to apply a lazy update to [left, right).

Implementations§

Source§

impl<Spec: LazySegTreeSpec> LazySegTree<Spec>

Source

pub fn new(size: usize) -> Self

Create a new tree of size elements, all initialized to Spec::ID.

max_size (the number of leaves used internally) will be the next power of two greater than or equal to size.

Source

pub fn from_vec(values: &[Spec::T]) -> Self

Build a tree from a slice of initial values. Complexity: O(n).

The slice length determines the logical size.

Examples found in repository?
examples/basic_usage.rs (line 156)
127fn custom_lazy_example() {
128    println!("4. Custom LazySegTree for Range Add + Range Sum");
129    println!("----------------------------------------------");
130
131    // Define a spec for range add operations with sum queries
132    struct RangeAddSum;
133
134    impl LazySegTreeSpec for RangeAddSum {
135        type T = i64; // Data type (stores sums)
136        type U = i64; // Update type (add values)
137        const ID: Self::T = 0;
138
139        // Combine two sum values
140        fn op_on_data(d1: &Self::T, d2: &Self::T) -> Self::T {
141            d1 + d2
142        }
143
144        // Compose two add operations
145        fn op_on_update(u1: &Self::U, u2: &Self::U) -> Self::U {
146            u1 + u2
147        }
148
149        // Apply add operation to sum (multiply by range size)
150        fn op_update_on_data(u: &Self::U, d: &Self::T, size: usize) -> Self::T {
151            d + u * (size as i64)
152        }
153    }
154
155    let values = vec![1i64, 2, 3, 4, 5];
156    let mut lazy_tree = LazySegTree::<RangeAddSum>::from_vec(&values);
157
158    println!("Initial values: {:?}", values);
159    println!("Initial sum [1, 4): {}", lazy_tree.query(1, 4)); // 2 + 3 + 4 = 9
160    println!("Initial sum [0, 5): {}", lazy_tree.query(0, 5)); // 15
161
162    // Add 10 to all elements in range [1, 4)
163    lazy_tree.update(1, 4, 10);
164    println!("\nAfter adding 10 to range [1, 4):");
165    println!("Sum [1, 4): {}", lazy_tree.query(1, 4)); // (2+10) + (3+10) + (4+10) = 39
166    println!("Sum [0, 5): {}", lazy_tree.query(0, 5)); // 1 + 12 + 13 + 14 + 5 = 45
167
168    // Add 5 to range [0, 2)
169    lazy_tree.update(0, 2, 5);
170    println!("\nAfter adding 5 to range [0, 2):");
171    println!("Sum [0, 2): {}", lazy_tree.query(0, 2)); // (1+5) + (12+5) = 23
172    println!("Sum [0, 5): {}", lazy_tree.query(0, 5)); // 6 + 17 + 13 + 14 + 5 = 55
173    println!();
174}
175
176/// Example 5: Using LazySegTree helper types
177fn lazy_helper_example() {
178    println!("5. LazySegTree Helper Types");
179    println!("--------------------------");
180
181    // Range add + range sum
182    let values = vec![2i32, 4, 6, 8, 10];
183    let mut sum_tree = LazySegTreeAddSum::<i32>::from_vec(&values);
184
185    println!("Initial values: {:?}", values);
186    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 30
187    println!("Sum [1, 4): {}", sum_tree.query(1, 4)); // 4 + 6 + 8 = 18
188
189    // Add 3 to range [1, 4)
190    sum_tree.update(1, 4, 3);
191    println!("\nAfter adding 3 to range [1, 4):");
192    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 2 + 7 + 9 + 11 + 10 = 39
193    println!("Sum [1, 4): {}", sum_tree.query(1, 4)); // 7 + 9 + 11 = 27
194
195    // Add -2 to range [0, 3)
196    sum_tree.update(0, 3, -2);
197    println!("\nAfter subtracting 2 from range [0, 3):");
198    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 0 + 5 + 7 + 11 + 10 = 33
199    println!("Sum [0, 3): {}", sum_tree.query(0, 3)); // 0 + 5 + 7 = 12
200
201    // Range add + range min
202    let min_values = vec![5, 2, 8, 1, 9, 3];
203    let mut min_tree = LazySegTreeAddMin::<i32>::from_vec(&min_values);
204    println!("\nInitial min values: {:?}", min_values);
205    println!("Min [0, 6): {}", min_tree.query(0, 6)); // 1
206    min_tree.update(1, 4, 2);
207    println!(
208        "After adding 2 to [1, 4): Min [0, 6): {}",
209        min_tree.query(0, 6)
210    ); // min(5, 4, 10, 3, 9, 3) = 3
211
212    // Range assignment (replace) + range sum
213    let rep_values = vec![1, 2, 3, 4, 5];
214    let mut rep_tree = LazySegTreeReplaceSum::<i32>::from_vec(&rep_values);
215    println!("\nInitial replace values: {:?}", rep_values);
216    println!("Sum [0, 5): {}", rep_tree.query(0, 5)); // 15
217    rep_tree.update(1, 4, 10); // Replace [1, 4) with 10
218    println!(
219        "After replacing [1, 4) with 10: Sum [0, 5): {}",
220        rep_tree.query(0, 5)
221    ); // 1 + 10 + 10 + 10 + 5 = 36
222    println!();
223}
224
225/// Example 6: Advanced lazy operations with overlapping updates
226fn advanced_lazy_example() {
227    println!("6. Advanced Lazy Operations");
228    println!("--------------------------");
229
230    let values = vec![1i32, 1, 1, 1, 1, 1, 1, 1]; // 8 ones
231    let mut tree = LazySegTreeAddSum::<i32>::from_vec(&values);
232
233    println!("Initial: 8 ones, sum = {}", tree.query(0, 8));
234
235    // Perform overlapping updates
236    tree.update(0, 4, 2); // Add 2 to first half
237    tree.update(2, 6, 3); // Add 3 to middle section (overlaps)
238    tree.update(4, 8, 1); // Add 1 to second half
239
240    println!("After overlapping updates:");
241    println!("Range [0, 2): sum = {}", tree.query(0, 2)); // (1+2) + (1+2) = 6
242    println!("Range [2, 4): sum = {}", tree.query(2, 4)); // (1+2+3) + (1+2+3) = 12
243    println!("Range [4, 6): sum = {}", tree.query(4, 6)); // (1+3+1) + (1+3+1) = 10
244    println!("Range [6, 8): sum = {}", tree.query(6, 8)); // (1+1) + (1+1) = 4
245    println!("Total sum: {}", tree.query(0, 8)); // 6 + 12 + 10 + 4 = 32
246
247    // Verify by querying individual ranges
248    let mut total = 0;
249    for i in 0..4 {
250        let range_sum = tree.query(i * 2, (i + 1) * 2);
251        total += range_sum;
252        println!("  Range [{}, {}): {}", i * 2, (i + 1) * 2, range_sum);
253    }
254    println!("Sum verification: {}", total);
255    println!();
256}
Source

pub fn query(&self, left: usize, right: usize) -> Spec::T

Query the half-open interval [left, right).

Returns Spec::ID for empty ranges (left == right). Panics if the range is invalid (see validate_range).

Examples found in repository?
examples/basic_usage.rs (line 159)
127fn custom_lazy_example() {
128    println!("4. Custom LazySegTree for Range Add + Range Sum");
129    println!("----------------------------------------------");
130
131    // Define a spec for range add operations with sum queries
132    struct RangeAddSum;
133
134    impl LazySegTreeSpec for RangeAddSum {
135        type T = i64; // Data type (stores sums)
136        type U = i64; // Update type (add values)
137        const ID: Self::T = 0;
138
139        // Combine two sum values
140        fn op_on_data(d1: &Self::T, d2: &Self::T) -> Self::T {
141            d1 + d2
142        }
143
144        // Compose two add operations
145        fn op_on_update(u1: &Self::U, u2: &Self::U) -> Self::U {
146            u1 + u2
147        }
148
149        // Apply add operation to sum (multiply by range size)
150        fn op_update_on_data(u: &Self::U, d: &Self::T, size: usize) -> Self::T {
151            d + u * (size as i64)
152        }
153    }
154
155    let values = vec![1i64, 2, 3, 4, 5];
156    let mut lazy_tree = LazySegTree::<RangeAddSum>::from_vec(&values);
157
158    println!("Initial values: {:?}", values);
159    println!("Initial sum [1, 4): {}", lazy_tree.query(1, 4)); // 2 + 3 + 4 = 9
160    println!("Initial sum [0, 5): {}", lazy_tree.query(0, 5)); // 15
161
162    // Add 10 to all elements in range [1, 4)
163    lazy_tree.update(1, 4, 10);
164    println!("\nAfter adding 10 to range [1, 4):");
165    println!("Sum [1, 4): {}", lazy_tree.query(1, 4)); // (2+10) + (3+10) + (4+10) = 39
166    println!("Sum [0, 5): {}", lazy_tree.query(0, 5)); // 1 + 12 + 13 + 14 + 5 = 45
167
168    // Add 5 to range [0, 2)
169    lazy_tree.update(0, 2, 5);
170    println!("\nAfter adding 5 to range [0, 2):");
171    println!("Sum [0, 2): {}", lazy_tree.query(0, 2)); // (1+5) + (12+5) = 23
172    println!("Sum [0, 5): {}", lazy_tree.query(0, 5)); // 6 + 17 + 13 + 14 + 5 = 55
173    println!();
174}
175
176/// Example 5: Using LazySegTree helper types
177fn lazy_helper_example() {
178    println!("5. LazySegTree Helper Types");
179    println!("--------------------------");
180
181    // Range add + range sum
182    let values = vec![2i32, 4, 6, 8, 10];
183    let mut sum_tree = LazySegTreeAddSum::<i32>::from_vec(&values);
184
185    println!("Initial values: {:?}", values);
186    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 30
187    println!("Sum [1, 4): {}", sum_tree.query(1, 4)); // 4 + 6 + 8 = 18
188
189    // Add 3 to range [1, 4)
190    sum_tree.update(1, 4, 3);
191    println!("\nAfter adding 3 to range [1, 4):");
192    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 2 + 7 + 9 + 11 + 10 = 39
193    println!("Sum [1, 4): {}", sum_tree.query(1, 4)); // 7 + 9 + 11 = 27
194
195    // Add -2 to range [0, 3)
196    sum_tree.update(0, 3, -2);
197    println!("\nAfter subtracting 2 from range [0, 3):");
198    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 0 + 5 + 7 + 11 + 10 = 33
199    println!("Sum [0, 3): {}", sum_tree.query(0, 3)); // 0 + 5 + 7 = 12
200
201    // Range add + range min
202    let min_values = vec![5, 2, 8, 1, 9, 3];
203    let mut min_tree = LazySegTreeAddMin::<i32>::from_vec(&min_values);
204    println!("\nInitial min values: {:?}", min_values);
205    println!("Min [0, 6): {}", min_tree.query(0, 6)); // 1
206    min_tree.update(1, 4, 2);
207    println!(
208        "After adding 2 to [1, 4): Min [0, 6): {}",
209        min_tree.query(0, 6)
210    ); // min(5, 4, 10, 3, 9, 3) = 3
211
212    // Range assignment (replace) + range sum
213    let rep_values = vec![1, 2, 3, 4, 5];
214    let mut rep_tree = LazySegTreeReplaceSum::<i32>::from_vec(&rep_values);
215    println!("\nInitial replace values: {:?}", rep_values);
216    println!("Sum [0, 5): {}", rep_tree.query(0, 5)); // 15
217    rep_tree.update(1, 4, 10); // Replace [1, 4) with 10
218    println!(
219        "After replacing [1, 4) with 10: Sum [0, 5): {}",
220        rep_tree.query(0, 5)
221    ); // 1 + 10 + 10 + 10 + 5 = 36
222    println!();
223}
224
225/// Example 6: Advanced lazy operations with overlapping updates
226fn advanced_lazy_example() {
227    println!("6. Advanced Lazy Operations");
228    println!("--------------------------");
229
230    let values = vec![1i32, 1, 1, 1, 1, 1, 1, 1]; // 8 ones
231    let mut tree = LazySegTreeAddSum::<i32>::from_vec(&values);
232
233    println!("Initial: 8 ones, sum = {}", tree.query(0, 8));
234
235    // Perform overlapping updates
236    tree.update(0, 4, 2); // Add 2 to first half
237    tree.update(2, 6, 3); // Add 3 to middle section (overlaps)
238    tree.update(4, 8, 1); // Add 1 to second half
239
240    println!("After overlapping updates:");
241    println!("Range [0, 2): sum = {}", tree.query(0, 2)); // (1+2) + (1+2) = 6
242    println!("Range [2, 4): sum = {}", tree.query(2, 4)); // (1+2+3) + (1+2+3) = 12
243    println!("Range [4, 6): sum = {}", tree.query(4, 6)); // (1+3+1) + (1+3+1) = 10
244    println!("Range [6, 8): sum = {}", tree.query(6, 8)); // (1+1) + (1+1) = 4
245    println!("Total sum: {}", tree.query(0, 8)); // 6 + 12 + 10 + 4 = 32
246
247    // Verify by querying individual ranges
248    let mut total = 0;
249    for i in 0..4 {
250        let range_sum = tree.query(i * 2, (i + 1) * 2);
251        total += range_sum;
252        println!("  Range [{}, {}): {}", i * 2, (i + 1) * 2, range_sum);
253    }
254    println!("Sum verification: {}", total);
255    println!();
256}
Source

pub fn update(&mut self, left: usize, right: usize, value: Spec::U)

Apply value lazily to the half-open interval [left, right).

Requires &mut self. Panics if range is invalid.

Examples found in repository?
examples/basic_usage.rs (line 163)
127fn custom_lazy_example() {
128    println!("4. Custom LazySegTree for Range Add + Range Sum");
129    println!("----------------------------------------------");
130
131    // Define a spec for range add operations with sum queries
132    struct RangeAddSum;
133
134    impl LazySegTreeSpec for RangeAddSum {
135        type T = i64; // Data type (stores sums)
136        type U = i64; // Update type (add values)
137        const ID: Self::T = 0;
138
139        // Combine two sum values
140        fn op_on_data(d1: &Self::T, d2: &Self::T) -> Self::T {
141            d1 + d2
142        }
143
144        // Compose two add operations
145        fn op_on_update(u1: &Self::U, u2: &Self::U) -> Self::U {
146            u1 + u2
147        }
148
149        // Apply add operation to sum (multiply by range size)
150        fn op_update_on_data(u: &Self::U, d: &Self::T, size: usize) -> Self::T {
151            d + u * (size as i64)
152        }
153    }
154
155    let values = vec![1i64, 2, 3, 4, 5];
156    let mut lazy_tree = LazySegTree::<RangeAddSum>::from_vec(&values);
157
158    println!("Initial values: {:?}", values);
159    println!("Initial sum [1, 4): {}", lazy_tree.query(1, 4)); // 2 + 3 + 4 = 9
160    println!("Initial sum [0, 5): {}", lazy_tree.query(0, 5)); // 15
161
162    // Add 10 to all elements in range [1, 4)
163    lazy_tree.update(1, 4, 10);
164    println!("\nAfter adding 10 to range [1, 4):");
165    println!("Sum [1, 4): {}", lazy_tree.query(1, 4)); // (2+10) + (3+10) + (4+10) = 39
166    println!("Sum [0, 5): {}", lazy_tree.query(0, 5)); // 1 + 12 + 13 + 14 + 5 = 45
167
168    // Add 5 to range [0, 2)
169    lazy_tree.update(0, 2, 5);
170    println!("\nAfter adding 5 to range [0, 2):");
171    println!("Sum [0, 2): {}", lazy_tree.query(0, 2)); // (1+5) + (12+5) = 23
172    println!("Sum [0, 5): {}", lazy_tree.query(0, 5)); // 6 + 17 + 13 + 14 + 5 = 55
173    println!();
174}
175
176/// Example 5: Using LazySegTree helper types
177fn lazy_helper_example() {
178    println!("5. LazySegTree Helper Types");
179    println!("--------------------------");
180
181    // Range add + range sum
182    let values = vec![2i32, 4, 6, 8, 10];
183    let mut sum_tree = LazySegTreeAddSum::<i32>::from_vec(&values);
184
185    println!("Initial values: {:?}", values);
186    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 30
187    println!("Sum [1, 4): {}", sum_tree.query(1, 4)); // 4 + 6 + 8 = 18
188
189    // Add 3 to range [1, 4)
190    sum_tree.update(1, 4, 3);
191    println!("\nAfter adding 3 to range [1, 4):");
192    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 2 + 7 + 9 + 11 + 10 = 39
193    println!("Sum [1, 4): {}", sum_tree.query(1, 4)); // 7 + 9 + 11 = 27
194
195    // Add -2 to range [0, 3)
196    sum_tree.update(0, 3, -2);
197    println!("\nAfter subtracting 2 from range [0, 3):");
198    println!("Sum [0, 5): {}", sum_tree.query(0, 5)); // 0 + 5 + 7 + 11 + 10 = 33
199    println!("Sum [0, 3): {}", sum_tree.query(0, 3)); // 0 + 5 + 7 = 12
200
201    // Range add + range min
202    let min_values = vec![5, 2, 8, 1, 9, 3];
203    let mut min_tree = LazySegTreeAddMin::<i32>::from_vec(&min_values);
204    println!("\nInitial min values: {:?}", min_values);
205    println!("Min [0, 6): {}", min_tree.query(0, 6)); // 1
206    min_tree.update(1, 4, 2);
207    println!(
208        "After adding 2 to [1, 4): Min [0, 6): {}",
209        min_tree.query(0, 6)
210    ); // min(5, 4, 10, 3, 9, 3) = 3
211
212    // Range assignment (replace) + range sum
213    let rep_values = vec![1, 2, 3, 4, 5];
214    let mut rep_tree = LazySegTreeReplaceSum::<i32>::from_vec(&rep_values);
215    println!("\nInitial replace values: {:?}", rep_values);
216    println!("Sum [0, 5): {}", rep_tree.query(0, 5)); // 15
217    rep_tree.update(1, 4, 10); // Replace [1, 4) with 10
218    println!(
219        "After replacing [1, 4) with 10: Sum [0, 5): {}",
220        rep_tree.query(0, 5)
221    ); // 1 + 10 + 10 + 10 + 5 = 36
222    println!();
223}
224
225/// Example 6: Advanced lazy operations with overlapping updates
226fn advanced_lazy_example() {
227    println!("6. Advanced Lazy Operations");
228    println!("--------------------------");
229
230    let values = vec![1i32, 1, 1, 1, 1, 1, 1, 1]; // 8 ones
231    let mut tree = LazySegTreeAddSum::<i32>::from_vec(&values);
232
233    println!("Initial: 8 ones, sum = {}", tree.query(0, 8));
234
235    // Perform overlapping updates
236    tree.update(0, 4, 2); // Add 2 to first half
237    tree.update(2, 6, 3); // Add 3 to middle section (overlaps)
238    tree.update(4, 8, 1); // Add 1 to second half
239
240    println!("After overlapping updates:");
241    println!("Range [0, 2): sum = {}", tree.query(0, 2)); // (1+2) + (1+2) = 6
242    println!("Range [2, 4): sum = {}", tree.query(2, 4)); // (1+2+3) + (1+2+3) = 12
243    println!("Range [4, 6): sum = {}", tree.query(4, 6)); // (1+3+1) + (1+3+1) = 10
244    println!("Range [6, 8): sum = {}", tree.query(6, 8)); // (1+1) + (1+1) = 4
245    println!("Total sum: {}", tree.query(0, 8)); // 6 + 12 + 10 + 4 = 32
246
247    // Verify by querying individual ranges
248    let mut total = 0;
249    for i in 0..4 {
250        let range_sum = tree.query(i * 2, (i + 1) * 2);
251        total += range_sum;
252        println!("  Range [{}, {}): {}", i * 2, (i + 1) * 2, range_sum);
253    }
254    println!("Sum verification: {}", total);
255    println!();
256}

Trait Implementations§

Source§

impl<Spec: Clone + LazySegTreeSpec> Clone for LazySegTree<Spec>
where Spec::T: Clone, Spec::U: Clone,

Source§

fn clone(&self) -> LazySegTree<Spec>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<Spec: Debug + LazySegTreeSpec> Debug for LazySegTree<Spec>
where Spec::T: Debug, Spec::U: Debug,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<Spec: LazySegTreeSpec> Display for LazySegTree<Spec>
where Spec::T: Display + PartialEq, Spec::U: Display,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<Spec> !Freeze for LazySegTree<Spec>

§

impl<Spec> !RefUnwindSafe for LazySegTree<Spec>

§

impl<Spec> Send for LazySegTree<Spec>
where Spec: Send, <Spec as LazySegTreeSpec>::T: Send, <Spec as LazySegTreeSpec>::U: Send,

§

impl<Spec> !Sync for LazySegTree<Spec>

§

impl<Spec> Unpin for LazySegTree<Spec>
where Spec: Unpin, <Spec as LazySegTreeSpec>::T: Unpin, <Spec as LazySegTreeSpec>::U: Unpin,

§

impl<Spec> UnwindSafe for LazySegTree<Spec>
where Spec: UnwindSafe, <Spec as LazySegTreeSpec>::T: UnwindSafe, <Spec as LazySegTreeSpec>::U: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.