| Crates.io | array_range_query |
| lib.rs | array_range_query |
| version | 0.2.3 |
| created_at | 2025-09-08 21:47:34.241205+00 |
| updated_at | 2025-10-23 22:32:35.576796+00 |
| description | High-performance generic segment tree and lazy segment tree implementations in Rust for efficient range queries, range updates, and interval operations. Supports custom monoid operations with zero-cost abstractions. |
| homepage | https://github.com/Sumanth-NR/array_range_query |
| repository | https://github.com/Sumanth-NR/array_range_query |
| max_upload_size | |
| id | 1829929 |
| size | 179,434 |
A high-performance, generic Rust implementation of Segment Trees and Lazy Segment Trees for efficient range queries, range updates, and interval operations.
Perfect for competitive programming, algorithm optimization, and solving range query problems with O(log n) time complexity.
A Segment Tree is a versatile data structure that allows you to:
(a ⊕ b) ⊕ c = a ⊕ (b ⊕ c))A Lazy Segment Tree extends this capability to efficiently handle:
Segment trees are essential for solving interval query problems efficiently:
| Operation | Naive Approach | Segment Tree | Improvement |
|---|---|---|---|
| Range Query | O(n) | O(log n) | Exponential speedup |
| Point Update | O(1) | O(log n) | Slightly slower |
| Range Update | O(n) | O(log n) with lazy | Exponential speedup |
| Data Structure | Range Query | Point Update | Range Update | Best For |
|---|---|---|---|---|
| Array | O(n) | O(1) | O(n) | Simple access |
| Prefix Sum | O(1) | O(n) | O(n) | Immutable sum queries |
| Segment Tree | O(log n) | O(log n) | O(n) | Dynamic range queries |
| Lazy Segment Tree | O(log n) | O(log n) | O(log n) | Range updates |
| Fenwick Tree (BIT) | O(log n) | O(log n) | - | Sum/XOR only |
| Sparse Table | O(1) | - | - | Immutable idempotent ops |
cargo add array_range_query
use array_range_query::SegTreeSum;
let values = vec![1, 2, 3, 4, 5];
let mut tree = SegTreeSum::<i32>::from_vec(values);
assert_eq!(tree.query(1..4), 9); // Sum of [2, 3, 4]
tree.update(2, 10); // Change index 2 to 10
assert_eq!(tree.query(..), 22); // Total sum: 1+2+10+4+5
use array_range_query::LazySegTreeAddSum;
let values = vec![1, 2, 3, 4, 5];
let mut tree = LazySegTreeAddSum::<i32>::from_vec(values);
assert_eq!(tree.query(1..4), 9); // Sum of [2, 3, 4]
tree.update(1..4, 10); // Add 10 to range [1, 4)
assert_eq!(tree.query(..), 45); // New total: 1+12+13+14+5
SegTreeSum<T> — Range sum queriesSegTreeMin<T> — Range minimum queriesSegTreeMax<T> — Range maximum queriesLazySegTreeAddSum<T> — Range add updates, sum queriesLazySegTreeAddMin<T> — Range add updates, min queriesLazySegTreeAddMax<T> — Range add updates, max queriesLazySegTreeReplaceSum<T> — Range assignment updates, sum queriesDefine your own operations by implementing the specification traits:
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 tree = SegTree::<MaxSpec>::from_vec(vec![3, 1, 4, 1, 5]);
assert_eq!(tree.query(..), 5); // Maximum element
For lazy segment trees:
use array_range_query::{LazySegTree, LazySegTreeSpec};
struct RangeAddSum;
impl LazySegTreeSpec for RangeAddSum {
type T = i64; // Data type
type U = i64; // Update type
const ID: Self::T = 0;
fn op_on_data(d1: &mut Self::T, d2: &Self::T) { *d1 += *d2; }
fn op_on_update(u1: &mut Self::U, u2: &Self::U) { *u1 += *u2; }
fn op_update_on_data(u: &Self::U, d: &mut Self::T, size: usize) {
*d += u * size as i64;
}
}
let mut tree = LazySegTree::<RangeAddSum>::from_vec(vec![1, 2, 3, 4, 5]);
tree.update(1..4, 10); // Add 10 to range [1, 4)
assert_eq!(tree.query(..), 45);
new(size) / from_slice(values) / from_vec(values) — Constructionquery(range) — Range query in O(log n)update(index, value) — Point update in O(log n)new(size) / from_slice(values) / from_vec(values) — Constructionquery(range) — Range query in O(log n)update(range, value) — Range update in O(log n)All query and update methods accept any range type:
2..5 (half-open)2..=4 (inclusive)..3 (from start)2.. (to end).. (entire range)Example: Given an array, answer queries for the sum of elements in any range and support updating individual elements.
use array_range_query::SegTreeSum;
let mut tree = SegTreeSum::<i32>::from_vec(vec![1, 3, 5, 7, 9, 11]);
// What's the sum from index 1 to 4?
assert_eq!(tree.query(1..4), 15); // 3 + 5 + 7
// Update index 2 to 10
tree.update(2, 10);
assert_eq!(tree.query(1..4), 20); // 3 + 10 + 7
Example: Find the minimum element in any subarray efficiently.
use array_range_query::SegTreeMin;
let tree = SegTreeMin::<i32>::from_vec(vec![4, 2, 8, 1, 9, 3, 6]);
assert_eq!(tree.query(1..5), 1); // min(2, 8, 1, 9) = 1
assert_eq!(tree.query(0..3), 2); // min(4, 2, 8) = 2
Example: Add a value to all elements in a range, then query range sums.
use array_range_query::LazySegTreeAddSum;
let mut tree = LazySegTreeAddSum::<i64>::from_vec(vec![1, 2, 3, 4, 5]);
// Add 10 to elements from index 1 to 3
tree.update(1..4, 10);
// Elements are now [1, 12, 13, 14, 5]
assert_eq!(tree.query(0..5), 45); // sum = 1+12+13+14+5
Example: Set all elements in a range to a specific value.
use array_range_query::LazySegTreeReplaceSum;
let mut tree = LazySegTreeReplaceSum::<i32>::from_vec(vec![1, 2, 3, 4, 5]);
// Set all elements from index 1 to 4 to value 10
tree.update(1..4, 10);
// Elements are now [1, 10, 10, 10, 5]
assert_eq!(tree.query(..), 36); // sum = 1+10+10+10+5
This library supports any monoid operation (associative operation with an identity element). Common examples:
Example of implementing GCD:
use array_range_query::{SegTree, SegTreeSpec};
struct GcdSpec;
impl SegTreeSpec for GcdSpec {
type T = u32;
const ID: Self::T = 0;
fn op(a: &mut Self::T, b: &Self::T) {
*a = gcd(*a, *b);
}
}
fn gcd(a: u32, b: u32) -> u32 {
if b == 0 { a } else { gcd(b, a % b) }
}
let tree = SegTree::<GcdSpec>::from_vec(vec![12, 18, 24, 30]);
assert_eq!(tree.query(..), 6); // GCD of all elements
Use Lazy Segment Trees when you need:
Examples: Range increment, range assignment, range multiplication.
Fenwick Tree (Binary Indexed Tree):
Sparse Table:
Segment Tree (this library):
num-traits, min_max_traitsThis library is relevant for:
Contributions are welcome! Please feel free to submit a Pull Request.
MIT License. See LICENSE for details.