SegTree

Struct SegTree 

Source
pub struct SegTree<Spec: SegTreeSpec> { /* private fields */ }
Expand description

A generic Segment Tree data structure.

A segment tree is a complete binary tree stored in a flat array that enables efficient range queries and point updates on sequences of elements. The tree supports any associative operation defined by the SegTreeSpec trait.

§Internal Structure

  • Uses 1-based indexing where the root is at index 1
  • Leaf nodes start at index max_size (next power of 2 ≥ size)
  • For any node at index i, its children are at 2*i and 2*i+1
  • Total space used is 2 * max_size

§Type Parameters

  • Spec - A type implementing SegTreeSpec that defines the operation and element type

§Examples

use array_range_query::{SegTree, SegTreeSpec};

struct MaxSpec;
impl SegTreeSpec for MaxSpec {
    type T = i32;
    const ID: Self::T = i32::MIN;
    fn op(a: &mut Self::T, b: &Self::T) { *a = (*a).max(*b); }
}

let values = vec![3, 1, 4, 1, 5, 9, 2];
let tree = SegTree::<MaxSpec>::from_vec(&values);
assert_eq!(tree.query(2..5), 5); // max(4, 1, 5) = 5

Implementations§

Source§

impl<Spec: SegTreeSpec> SegTree<Spec>

Source

pub fn new(size: usize) -> Self

Creates a new SegTree of a given size, initialized with identity elements.

All elements in the tree are initialized to Spec::ID. The internal tree size (max_size) will be the smallest power of two greater than or equal to size for optimal tree structure and performance.

§Time Complexity

O(n) where n is the smallest power of two ≥ size.

§Examples
use array_range_query::{SegTree, SegTreeSpec};

struct SumSpec;
impl SegTreeSpec for SumSpec {
    type T = i64;
    const ID: Self::T = 0;
    fn op(a: &mut Self::T, b: &Self::T) { *a += *b; }
}

let tree = SegTree::<SumSpec>::new(100);
assert_eq!(tree.query(..), 0); // All elements are 0 (identity)
Source

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

Creates a new SegTree from a vector of initial values.

The tree is built in O(n) time using a bottom-up approach, which is more efficient than creating an empty tree and updating each element individually. This is the recommended way to initialize a segment tree with known values.

§Time Complexity

O(n) where n is the length of values.

§Examples
use array_range_query::{SegTree, SegTreeSpec};

struct SumSpec;
impl SegTreeSpec for SumSpec {
    type T = i64;
    const ID: Self::T = 0;
    fn op(a: &mut Self::T, b: &Self::T) { *a += *b; }
}

let values = vec![1, 2, 3, 4, 5];
let tree = SegTree::<SumSpec>::from_vec(&values);
assert_eq!(tree.query(..), 15); // Sum of all elements
assert_eq!(tree.query(1..4), 9); // Sum of elements [2, 3, 4]
Examples found in repository?
examples/basic_usage.rs (line 53)
36fn custom_sum_example() {
37    println!("1. Custom SegTree for Sum Operations");
38    println!("-----------------------------------");
39
40    // Define a custom spec for sum operations
41    struct SumSpec;
42
43    impl SegTreeSpec for SumSpec {
44        type T = i64;
45        const ID: Self::T = 0; // Identity element for addition
46
47        fn op(a: &mut Self::T, b: &Self::T) {
48            *a += *b;
49        }
50    }
51
52    let values = vec![1, 2, 3, 4, 5];
53    let mut seg_tree = SegTree::<SumSpec>::from_vec(&values);
54
55    println!("Initial values: {:?}", values);
56    println!("Sum of range [1, 4): {}", seg_tree.query(1..4)); // 2 + 3 + 4 = 9
57    println!("Sum of entire array [0, 5): {}", seg_tree.query(..)); // 15
58
59    // Update element at index 2 from 3 to 10
60    seg_tree.update(2, 10);
61    println!("\nAfter updating index 2 to 10:");
62    println!("Sum of range [1, 4): {}", seg_tree.query(1..4)); // 2 + 10 + 4 = 16
63    println!("Sum of entire array [0, 5): {}", seg_tree.query(..)); // 22
64    println!();
65}
66
67/// Example 2: Using helper types for common operations
68fn helper_types_example() {
69    println!("2. Helper Types for Common Operations");
70    println!("------------------------------------");
71
72    let values = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
73    println!("Values: {:?}", values);
74
75    // Sum operations
76    let mut sum_tree = SegTreeSum::<i32>::from_vec(&values);
77    println!("Range sum [2, 6): {}", sum_tree.query(2..6)); // 4 + 1 + 5 + 9 = 19
78
79    // Min operations
80    let mut min_tree = SegTreeMin::<i32>::from_vec(&values);
81    println!("Range min [2, 6): {}", min_tree.query(2..6)); // min(4, 1, 5, 9) = 1
82
83    // Max operations
84    let mut max_tree = SegTreeMax::<i32>::from_vec(&values);
85    println!("Range max [2, 6): {}", max_tree.query(2..6)); // max(4, 1, 5, 9) = 9
86
87    // Demonstrate updates
88    println!("\nAfter updating index 3 to 20:");
89    sum_tree.update(3, 20);
90    min_tree.update(3, 20);
91    max_tree.update(3, 20);
92
93    println!("Range sum [2, 6): {}", sum_tree.query(2..6)); // 4 + 20 + 5 + 9 = 38
94    println!("Range min [2, 6): {}", min_tree.query(2..6)); // min(4, 20, 5, 9) = 4
95    println!("Range max [2, 6): {}", max_tree.query(2..6)); // max(4, 20, 5, 9) = 20
96    println!();
97}
98
99/// Example 3: Custom min operation with detailed explanation
100fn custom_min_example() {
101    println!("3. Custom Min Operation with Details");
102    println!("-----------------------------------");
103
104    struct MinSpec;
105
106    impl SegTreeSpec for MinSpec {
107        type T = i32;
108        const ID: Self::T = i32::MAX; // Identity for min is maximum possible value
109
110        fn op(a: &mut Self::T, b: &Self::T) {
111            if *a > *b {
112                *a = *b;
113            }
114        }
115    }
116
117    let values = vec![7, 3, 9, 1, 6, 2, 8, 4];
118    let seg_tree = SegTree::<MinSpec>::from_vec(&values);
119
120    println!("Values: {:?}", values);
121    println!("Min of entire array: {}", seg_tree.query(..)); // 1
122    println!("Min of [2, 5): {}", seg_tree.query(2..5)); // min(9, 1, 6) = 1
123    println!("Min of [0, 3): {}", seg_tree.query(..3)); // min(7, 3, 9) = 3
124    println!("Min of [5, 8): {}", seg_tree.query(5..)); // min(2, 8, 4) = 2
125    println!();
126}
Source

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

Creates a new SegTree from a mutable vector of initial values.

Similar to from_vec, but takes a mutable reference to the input values. This can be useful when you already have a mutable reference and want to avoid additional borrowing constraints.

§Time Complexity

O(n) where n is the length of values.

§Examples
use array_range_query::{SegTree, SegTreeSpec};

struct SumSpec;
impl SegTreeSpec for SumSpec {
    type T = i64;
    const ID: Self::T = 0;
    fn op(a: &mut Self::T, b: &Self::T) { *a += *b; }
}

let mut values = vec![1, 2, 3, 4, 5];
let tree = SegTree::<SumSpec>::from_mut_vec(&mut values);
assert_eq!(tree.query(..), 15);
Source

pub fn query<R: RangeBounds<usize>>(&self, range: R) -> Spec::T

Queries the segment tree for the aggregated value in the given range.

Returns the result of applying the monoid operation across all elements in the specified range. 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
  • If the start of the range is greater than the end
  • If the end of the range is out of bounds (> self.size)
§Examples
use array_range_query::{SegTree, SegTreeSpec};

struct SumSpec;
impl SegTreeSpec for SumSpec {
    type T = i64;
    const ID: Self::T = 0;
    fn op(a: &mut Self::T, b: &Self::T) { *a += *b; }
}

let values = vec![1, 2, 3, 4, 5];
let tree = SegTree::<SumSpec>::from_vec(&values);

assert_eq!(tree.query(..), 15);      // All elements: 1+2+3+4+5
assert_eq!(tree.query(1..4), 9);     // Elements [1,4): 2+3+4
assert_eq!(tree.query(2..=4), 12);   // Elements [2,4]: 3+4+5
assert_eq!(tree.query(..3), 6);      // Elements [0,3): 1+2+3
assert_eq!(tree.query(2..), 12);     // Elements [2,∞): 3+4+5
Examples found in repository?
examples/basic_usage.rs (line 56)
36fn custom_sum_example() {
37    println!("1. Custom SegTree for Sum Operations");
38    println!("-----------------------------------");
39
40    // Define a custom spec for sum operations
41    struct SumSpec;
42
43    impl SegTreeSpec for SumSpec {
44        type T = i64;
45        const ID: Self::T = 0; // Identity element for addition
46
47        fn op(a: &mut Self::T, b: &Self::T) {
48            *a += *b;
49        }
50    }
51
52    let values = vec![1, 2, 3, 4, 5];
53    let mut seg_tree = SegTree::<SumSpec>::from_vec(&values);
54
55    println!("Initial values: {:?}", values);
56    println!("Sum of range [1, 4): {}", seg_tree.query(1..4)); // 2 + 3 + 4 = 9
57    println!("Sum of entire array [0, 5): {}", seg_tree.query(..)); // 15
58
59    // Update element at index 2 from 3 to 10
60    seg_tree.update(2, 10);
61    println!("\nAfter updating index 2 to 10:");
62    println!("Sum of range [1, 4): {}", seg_tree.query(1..4)); // 2 + 10 + 4 = 16
63    println!("Sum of entire array [0, 5): {}", seg_tree.query(..)); // 22
64    println!();
65}
66
67/// Example 2: Using helper types for common operations
68fn helper_types_example() {
69    println!("2. Helper Types for Common Operations");
70    println!("------------------------------------");
71
72    let values = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
73    println!("Values: {:?}", values);
74
75    // Sum operations
76    let mut sum_tree = SegTreeSum::<i32>::from_vec(&values);
77    println!("Range sum [2, 6): {}", sum_tree.query(2..6)); // 4 + 1 + 5 + 9 = 19
78
79    // Min operations
80    let mut min_tree = SegTreeMin::<i32>::from_vec(&values);
81    println!("Range min [2, 6): {}", min_tree.query(2..6)); // min(4, 1, 5, 9) = 1
82
83    // Max operations
84    let mut max_tree = SegTreeMax::<i32>::from_vec(&values);
85    println!("Range max [2, 6): {}", max_tree.query(2..6)); // max(4, 1, 5, 9) = 9
86
87    // Demonstrate updates
88    println!("\nAfter updating index 3 to 20:");
89    sum_tree.update(3, 20);
90    min_tree.update(3, 20);
91    max_tree.update(3, 20);
92
93    println!("Range sum [2, 6): {}", sum_tree.query(2..6)); // 4 + 20 + 5 + 9 = 38
94    println!("Range min [2, 6): {}", min_tree.query(2..6)); // min(4, 20, 5, 9) = 4
95    println!("Range max [2, 6): {}", max_tree.query(2..6)); // max(4, 20, 5, 9) = 20
96    println!();
97}
98
99/// Example 3: Custom min operation with detailed explanation
100fn custom_min_example() {
101    println!("3. Custom Min Operation with Details");
102    println!("-----------------------------------");
103
104    struct MinSpec;
105
106    impl SegTreeSpec for MinSpec {
107        type T = i32;
108        const ID: Self::T = i32::MAX; // Identity for min is maximum possible value
109
110        fn op(a: &mut Self::T, b: &Self::T) {
111            if *a > *b {
112                *a = *b;
113            }
114        }
115    }
116
117    let values = vec![7, 3, 9, 1, 6, 2, 8, 4];
118    let seg_tree = SegTree::<MinSpec>::from_vec(&values);
119
120    println!("Values: {:?}", values);
121    println!("Min of entire array: {}", seg_tree.query(..)); // 1
122    println!("Min of [2, 5): {}", seg_tree.query(2..5)); // min(9, 1, 6) = 1
123    println!("Min of [0, 3): {}", seg_tree.query(..3)); // min(7, 3, 9) = 3
124    println!("Min of [5, 8): {}", seg_tree.query(5..)); // min(2, 8, 4) = 2
125    println!();
126}
Source

pub fn update(&mut self, index: usize, value: Spec::T)

Performs a point update, replacing the value at index with a new value.

After updating the leaf node, the change is propagated up the tree by recalculating all ancestor nodes. This maintains the tree invariant that each internal node contains the aggregate of its subtree.

§Time Complexity

O(log n)

§Panics

Panics if index >= self.size (index out of bounds).

§Examples
use array_range_query::{SegTree, SegTreeSpec};

struct SumSpec;
impl SegTreeSpec for SumSpec {
    type T = i64;
    const ID: Self::T = 0;
    fn op(a: &mut Self::T, b: &Self::T) { *a += *b; }
}

let values = vec![1, 2, 3, 4, 5];
let mut tree = SegTree::<SumSpec>::from_vec(&values);

assert_eq!(tree.query(..), 15);  // Original sum

tree.update(2, 10);              // Change 3 to 10
assert_eq!(tree.query(..), 22);  // New sum: 1+2+10+4+5
assert_eq!(tree.query(2..3), 10); // Just the updated element
Examples found in repository?
examples/basic_usage.rs (line 60)
36fn custom_sum_example() {
37    println!("1. Custom SegTree for Sum Operations");
38    println!("-----------------------------------");
39
40    // Define a custom spec for sum operations
41    struct SumSpec;
42
43    impl SegTreeSpec for SumSpec {
44        type T = i64;
45        const ID: Self::T = 0; // Identity element for addition
46
47        fn op(a: &mut Self::T, b: &Self::T) {
48            *a += *b;
49        }
50    }
51
52    let values = vec![1, 2, 3, 4, 5];
53    let mut seg_tree = SegTree::<SumSpec>::from_vec(&values);
54
55    println!("Initial values: {:?}", values);
56    println!("Sum of range [1, 4): {}", seg_tree.query(1..4)); // 2 + 3 + 4 = 9
57    println!("Sum of entire array [0, 5): {}", seg_tree.query(..)); // 15
58
59    // Update element at index 2 from 3 to 10
60    seg_tree.update(2, 10);
61    println!("\nAfter updating index 2 to 10:");
62    println!("Sum of range [1, 4): {}", seg_tree.query(1..4)); // 2 + 10 + 4 = 16
63    println!("Sum of entire array [0, 5): {}", seg_tree.query(..)); // 22
64    println!();
65}
66
67/// Example 2: Using helper types for common operations
68fn helper_types_example() {
69    println!("2. Helper Types for Common Operations");
70    println!("------------------------------------");
71
72    let values = vec![3, 1, 4, 1, 5, 9, 2, 6, 5, 3];
73    println!("Values: {:?}", values);
74
75    // Sum operations
76    let mut sum_tree = SegTreeSum::<i32>::from_vec(&values);
77    println!("Range sum [2, 6): {}", sum_tree.query(2..6)); // 4 + 1 + 5 + 9 = 19
78
79    // Min operations
80    let mut min_tree = SegTreeMin::<i32>::from_vec(&values);
81    println!("Range min [2, 6): {}", min_tree.query(2..6)); // min(4, 1, 5, 9) = 1
82
83    // Max operations
84    let mut max_tree = SegTreeMax::<i32>::from_vec(&values);
85    println!("Range max [2, 6): {}", max_tree.query(2..6)); // max(4, 1, 5, 9) = 9
86
87    // Demonstrate updates
88    println!("\nAfter updating index 3 to 20:");
89    sum_tree.update(3, 20);
90    min_tree.update(3, 20);
91    max_tree.update(3, 20);
92
93    println!("Range sum [2, 6): {}", sum_tree.query(2..6)); // 4 + 20 + 5 + 9 = 38
94    println!("Range min [2, 6): {}", min_tree.query(2..6)); // min(4, 20, 5, 9) = 4
95    println!("Range max [2, 6): {}", max_tree.query(2..6)); // max(4, 20, 5, 9) = 20
96    println!();
97}

Auto Trait Implementations§

§

impl<Spec> Freeze for SegTree<Spec>

§

impl<Spec> RefUnwindSafe for SegTree<Spec>
where Spec: RefUnwindSafe, <Spec as SegTreeSpec>::T: RefUnwindSafe,

§

impl<Spec> Send for SegTree<Spec>
where Spec: Send, <Spec as SegTreeSpec>::T: Send,

§

impl<Spec> Sync for SegTree<Spec>
where Spec: Sync, <Spec as SegTreeSpec>::T: Sync,

§

impl<Spec> Unpin for SegTree<Spec>
where Spec: Unpin, <Spec as SegTreeSpec>::T: Unpin,

§

impl<Spec> UnwindSafe for SegTree<Spec>
where Spec: UnwindSafe, <Spec as SegTreeSpec>::T: 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> 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, 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.