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 at2*iand2*i+1 - Total space used is
2 * max_size
§Type Parameters
Spec- A type implementingSegTreeSpecthat 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) = 5Implementations§
Source§impl<Spec: SegTreeSpec> SegTree<Spec>
impl<Spec: SegTreeSpec> SegTree<Spec>
Sourcepub fn new(size: usize) -> Self
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)Sourcepub fn from_vec(values: &[Spec::T]) -> Self
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?
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}Sourcepub fn from_mut_vec(values: &mut [Spec::T]) -> Self
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);Sourcepub fn query<R: RangeBounds<usize>>(&self, range: R) -> Spec::T
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+5Examples found in repository?
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}Sourcepub fn update(&mut self, index: usize, value: Spec::T)
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 elementExamples found in repository?
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}