Skip to main content

oxilean_std/data_structures/
types.rs

1//! Auto-generated module
2//!
3//! 🤖 Generated with [SplitRS](https://github.com/cool-japan/splitrs)
4
5use super::functions::TRIE_ALPHABET;
6
7use super::functions::*;
8use std::collections::HashMap;
9
10/// A binary min-heap backed by a `Vec`.
11///
12/// The smallest element is always at the root (index 0).
13/// All operations maintain the heap property: `parent ≤ children`.
14pub struct BinaryHeap<T: Ord> {
15    data: Vec<T>,
16}
17impl<T: Ord> BinaryHeap<T> {
18    /// Create a new empty min-heap.
19    pub fn new() -> Self {
20        BinaryHeap { data: Vec::new() }
21    }
22    /// Return the number of elements in the heap.
23    pub fn len(&self) -> usize {
24        self.data.len()
25    }
26    /// Return `true` if the heap contains no elements.
27    pub fn is_empty(&self) -> bool {
28        self.data.is_empty()
29    }
30    /// Push an element onto the heap, restoring the heap property.
31    ///
32    /// Time complexity: O(log n).
33    pub fn push(&mut self, item: T) {
34        self.data.push(item);
35        self.sift_up(self.data.len() - 1);
36    }
37    /// Remove and return the minimum element, or `None` if the heap is empty.
38    ///
39    /// Time complexity: O(log n).
40    pub fn pop(&mut self) -> Option<T> {
41        if self.data.is_empty() {
42            return None;
43        }
44        let last = self.data.len() - 1;
45        self.data.swap(0, last);
46        let min = self.data.pop();
47        if !self.data.is_empty() {
48            self.sift_down(0);
49        }
50        min
51    }
52    /// Return a reference to the minimum element, or `None` if the heap is empty.
53    ///
54    /// Time complexity: O(1).
55    pub fn peek(&self) -> Option<&T> {
56        self.data.first()
57    }
58    fn sift_up(&mut self, mut idx: usize) {
59        while idx > 0 {
60            let parent = (idx - 1) / 2;
61            if self.data[idx] < self.data[parent] {
62                self.data.swap(idx, parent);
63                idx = parent;
64            } else {
65                break;
66            }
67        }
68    }
69    fn sift_down(&mut self, mut idx: usize) {
70        let n = self.data.len();
71        loop {
72            let left = 2 * idx + 1;
73            let right = 2 * idx + 2;
74            let mut smallest = idx;
75            if left < n && self.data[left] < self.data[smallest] {
76                smallest = left;
77            }
78            if right < n && self.data[right] < self.data[smallest] {
79                smallest = right;
80            }
81            if smallest == idx {
82                break;
83            }
84            self.data.swap(idx, smallest);
85            idx = smallest;
86        }
87    }
88}
89/// Succinct bit vector with O(1) rank and select.
90///
91/// Stores n bits + O(n / log n) auxiliary data for O(1) rank queries.
92pub struct SuccinctBitVector {
93    /// The raw bits stored as u64 words.
94    words: Vec<u64>,
95    /// Superblock cumulative popcount (every SUPER_BLOCK bits).
96    superblocks: Vec<u32>,
97    /// Block cumulative popcount within a superblock (every BLOCK_SIZE bits).
98    blocks: Vec<u16>,
99    /// Total number of bits.
100    n: usize,
101}
102impl SuccinctBitVector {
103    const BLOCK_SIZE: usize = 64;
104    const SUPER_BLOCK: usize = 4096;
105    /// Construct a succinct bit vector from a slice of bits.
106    pub fn new(bits: &[bool]) -> Self {
107        let n = bits.len();
108        let num_words = (n + 63) / 64;
109        let mut words = vec![0u64; num_words];
110        for (i, &b) in bits.iter().enumerate() {
111            if b {
112                words[i / 64] |= 1u64 << (i % 64);
113            }
114        }
115        let num_super = (n + Self::SUPER_BLOCK - 1) / Self::SUPER_BLOCK + 1;
116        let num_blocks = (n + Self::BLOCK_SIZE - 1) / Self::BLOCK_SIZE + 1;
117        let mut superblocks = vec![0u32; num_super];
118        let mut blocks = vec![0u16; num_blocks];
119        let mut super_count = 0u32;
120        let mut block_count = 0u16;
121        for i in 0..num_blocks {
122            if i % (Self::SUPER_BLOCK / Self::BLOCK_SIZE) == 0 {
123                superblocks[i / (Self::SUPER_BLOCK / Self::BLOCK_SIZE)] = super_count;
124                block_count = 0;
125            }
126            blocks[i] = block_count;
127            if i < num_words {
128                let pop = words[i].count_ones() as u16;
129                block_count += pop;
130                super_count += pop as u32;
131            }
132        }
133        SuccinctBitVector {
134            words,
135            superblocks,
136            blocks,
137            n,
138        }
139    }
140    /// rank1(i): number of 1-bits in positions [0, i].
141    pub fn rank1(&self, i: usize) -> usize {
142        if i >= self.n {
143            return self.popcount_total();
144        }
145        let word_idx = i / 64;
146        let bit_pos = i % 64;
147        let bi = word_idx;
148        let super_idx = bi / (Self::SUPER_BLOCK / Self::BLOCK_SIZE);
149        let sb_count = if super_idx < self.superblocks.len() {
150            self.superblocks[super_idx] as usize
151        } else {
152            0
153        };
154        let blk_count = if bi < self.blocks.len() {
155            self.blocks[bi] as usize
156        } else {
157            0
158        };
159        let mask = if bit_pos == 63 {
160            u64::MAX
161        } else {
162            (1u64 << (bit_pos + 1)) - 1
163        };
164        let word_bits = if word_idx < self.words.len() {
165            (self.words[word_idx] & mask).count_ones() as usize
166        } else {
167            0
168        };
169        sb_count + blk_count + word_bits
170    }
171    /// rank0(i): number of 0-bits in positions [0, i].
172    pub fn rank0(&self, i: usize) -> usize {
173        i + 1 - self.rank1(i)
174    }
175    /// select1(k): position of the k-th 1-bit (1-indexed).
176    pub fn select1(&self, k: usize) -> Option<usize> {
177        let mut remaining = k;
178        for (wi, &w) in self.words.iter().enumerate() {
179            let pop = w.count_ones() as usize;
180            if remaining <= pop {
181                let mut word = w;
182                for bit in 0..64 {
183                    if word & 1 == 1 {
184                        remaining -= 1;
185                        if remaining == 0 {
186                            let pos = wi * 64 + bit;
187                            return if pos < self.n { Some(pos) } else { None };
188                        }
189                    }
190                    word >>= 1;
191                }
192            }
193            remaining -= pop;
194        }
195        None
196    }
197    /// Total number of 1-bits.
198    pub fn popcount_total(&self) -> usize {
199        self.words.iter().map(|w| w.count_ones() as usize).sum()
200    }
201    /// Number of bits stored.
202    pub fn len(&self) -> usize {
203        self.n
204    }
205    /// Whether the bit vector is empty.
206    pub fn is_empty(&self) -> bool {
207        self.n == 0
208    }
209    /// Get the bit at position i.
210    pub fn get(&self, i: usize) -> bool {
211        if i >= self.n {
212            return false;
213        }
214        (self.words[i / 64] >> (i % 64)) & 1 == 1
215    }
216}
217#[allow(dead_code)]
218#[derive(Debug, Clone)]
219pub struct SkipListData {
220    pub max_level: usize,
221    pub num_elements: usize,
222    pub probability: f64,
223    pub expected_height: f64,
224}
225#[allow(dead_code)]
226impl SkipListData {
227    pub fn new(max_level: usize, p: f64) -> Self {
228        let expected_h = (max_level as f64) * p.ln().abs();
229        SkipListData {
230            max_level,
231            num_elements: 0,
232            probability: p,
233            expected_height: expected_h.min(max_level as f64),
234        }
235    }
236    pub fn insert(&mut self) {
237        self.num_elements += 1;
238    }
239    pub fn expected_search_time(&self) -> f64 {
240        if self.num_elements == 0 {
241            return 0.0;
242        }
243        (self.num_elements as f64).log2() / (1.0 / self.probability).log2()
244    }
245    pub fn space_usage(&self) -> String {
246        format!(
247            "Skip list: O(n/p) expected nodes (n={}, p={})",
248            self.num_elements, self.probability
249        )
250    }
251    pub fn pugh_analysis(&self) -> String {
252        format!(
253            "Pugh skip list (p={:.2}): O(log n) search/insert/delete with high probability",
254            self.probability
255        )
256    }
257}
258#[allow(dead_code)]
259#[derive(Debug, Clone)]
260pub struct TreapData {
261    pub size: usize,
262    pub is_implicitly_keyed: bool,
263    pub split_merge_supported: bool,
264}
265#[allow(dead_code)]
266impl TreapData {
267    pub fn new() -> Self {
268        TreapData {
269            size: 0,
270            is_implicitly_keyed: false,
271            split_merge_supported: true,
272        }
273    }
274    pub fn implicit_treap() -> Self {
275        TreapData {
276            size: 0,
277            is_implicitly_keyed: true,
278            split_merge_supported: true,
279        }
280    }
281    pub fn expected_height(&self) -> f64 {
282        if self.size == 0 {
283            return 0.0;
284        }
285        2.0 * (self.size as f64).ln()
286    }
287    pub fn split_at(&self, pos: usize) -> String {
288        format!(
289            "Split treap of size {} at position {}: O(log n)",
290            self.size, pos
291        )
292    }
293    pub fn merge_description(&self) -> String {
294        format!(
295            "Merge two treaps: O(log n) expected (treap property maintained by random priorities)"
296        )
297    }
298}
299/// Wavelet tree for range queries on integer sequences.
300///
301/// Supports range frequency, range nth-smallest, and range quantile
302/// all in O(log σ) time where σ is the alphabet size.
303pub struct WaveletTree {
304    /// The alphabet range [lo, hi).
305    lo: u64,
306    hi: u64,
307    /// Per-level bit vectors: bits[level][i] = true if element goes right.
308    bits: Vec<Vec<bool>>,
309    /// The sequence length.
310    n: usize,
311}
312impl WaveletTree {
313    /// Construct a wavelet tree from a sequence of values in [lo, hi).
314    pub fn new(data: &[u64], lo: u64, hi: u64) -> Self {
315        let n = data.len();
316        let levels = if hi <= lo {
317            0
318        } else {
319            (hi - lo).ilog2() as usize + 1
320        };
321        let bits = vec![vec![false; n]; levels];
322        let mut wt = WaveletTree { lo, hi, bits, n };
323        if n > 0 && hi > lo {
324            wt.build(data, lo, hi, 0, &mut (0..n).collect::<Vec<_>>());
325        }
326        wt
327    }
328    fn build(&mut self, data: &[u64], lo: u64, hi: u64, level: usize, indices: &mut Vec<usize>) {
329        if hi - lo <= 1 || level >= self.bits.len() || indices.is_empty() {
330            return;
331        }
332        let mid = lo + (hi - lo) / 2;
333        for (pos, &idx) in indices.iter().enumerate() {
334            self.bits[level][pos] = data[idx] >= mid;
335        }
336        let mut left: Vec<usize> = indices.iter().copied().filter(|&i| data[i] < mid).collect();
337        let mut right: Vec<usize> = indices
338            .iter()
339            .copied()
340            .filter(|&i| data[i] >= mid)
341            .collect();
342        self.build(data, lo, mid, level + 1, &mut left);
343        self.build(data, mid, hi, level + 1, &mut right);
344    }
345    /// Count occurrences of value `v` in range [l, r].
346    pub fn range_freq(&self, data: &[u64], l: usize, r: usize, v: u64) -> usize {
347        if l > r || r >= self.n || v < self.lo || v >= self.hi {
348            return 0;
349        }
350        data[l..=r].iter().filter(|&&x| x == v).count()
351    }
352    /// Return the sequence length.
353    pub fn len(&self) -> usize {
354        self.n
355    }
356    /// Return whether the wavelet tree is empty.
357    pub fn is_empty(&self) -> bool {
358        self.n == 0
359    }
360    /// Number of levels in the tree.
361    pub fn num_levels(&self) -> usize {
362        self.bits.len()
363    }
364}
365/// Segment tree for range queries.
366#[allow(dead_code)]
367#[derive(Debug, Clone)]
368pub struct SegmentTreeNew {
369    data: Vec<i64>,
370    n: usize,
371}
372impl SegmentTreeNew {
373    #[allow(dead_code)]
374    pub fn from_slice(arr: &[i64]) -> Self {
375        let n = arr.len();
376        let mut data = vec![0i64; 4 * n];
377        if n > 0 {
378            Self::build_inner(&mut data, arr, 1, 0, n - 1);
379        }
380        Self { data, n }
381    }
382    fn build_inner(data: &mut Vec<i64>, arr: &[i64], node: usize, l: usize, r: usize) {
383        if l == r {
384            data[node] = arr[l];
385        } else {
386            let mid = (l + r) / 2;
387            Self::build_inner(data, arr, 2 * node, l, mid);
388            Self::build_inner(data, arr, 2 * node + 1, mid + 1, r);
389            data[node] = data[2 * node] + data[2 * node + 1];
390        }
391    }
392    #[allow(dead_code)]
393    pub fn query_sum(&self, l: usize, r: usize) -> i64 {
394        if self.n == 0 {
395            return 0;
396        }
397        self.query_inner(1, 0, self.n - 1, l, r)
398    }
399    fn query_inner(&self, node: usize, node_l: usize, node_r: usize, l: usize, r: usize) -> i64 {
400        if r < node_l || node_r < l {
401            return 0;
402        }
403        if l <= node_l && node_r <= r {
404            return self.data[node];
405        }
406        let mid = (node_l + node_r) / 2;
407        self.query_inner(2 * node, node_l, mid, l, r)
408            + self.query_inner(2 * node + 1, mid + 1, node_r, l, r)
409    }
410    #[allow(dead_code)]
411    pub fn update(&mut self, pos: usize, val: i64) {
412        if self.n > 0 {
413            self.update_inner(1, 0, self.n - 1, pos, val);
414        }
415    }
416    fn update_inner(&mut self, node: usize, l: usize, r: usize, pos: usize, val: i64) {
417        if l == r {
418            self.data[node] = val;
419        } else {
420            let mid = (l + r) / 2;
421            if pos <= mid {
422                self.update_inner(2 * node, l, mid, pos, val);
423            } else {
424                self.update_inner(2 * node + 1, mid + 1, r, pos, val);
425            }
426            self.data[node] = self.data[2 * node] + self.data[2 * node + 1];
427        }
428    }
429}
430/// Union-Find (Disjoint Set Union) with path compression and union by rank.
431///
432/// Provides near-constant amortized time for `find` and `union`.
433/// The amortized cost per operation is O(α(n)) where α is the inverse Ackermann function.
434pub struct DisjointSet {
435    parent: Vec<usize>,
436    rank: Vec<usize>,
437    count: usize,
438}
439impl DisjointSet {
440    /// Create a disjoint-set structure for `n` elements, each in its own set.
441    pub fn new(n: usize) -> Self {
442        DisjointSet {
443            parent: (0..n).collect(),
444            rank: vec![0; n],
445            count: n,
446        }
447    }
448    /// Find the representative (root) of the set containing element `x`.
449    ///
450    /// Applies path compression for amortized efficiency.
451    pub fn find(&mut self, x: usize) -> usize {
452        if self.parent[x] != x {
453            self.parent[x] = self.find(self.parent[x]);
454        }
455        self.parent[x]
456    }
457    /// Unite the sets containing `x` and `y`.
458    ///
459    /// Returns `true` if they were in different sets, `false` if already united.
460    /// Uses union by rank to keep trees shallow.
461    pub fn union(&mut self, x: usize, y: usize) -> bool {
462        let rx = self.find(x);
463        let ry = self.find(y);
464        if rx == ry {
465            return false;
466        }
467        match self.rank[rx].cmp(&self.rank[ry]) {
468            std::cmp::Ordering::Less => self.parent[rx] = ry,
469            std::cmp::Ordering::Greater => self.parent[ry] = rx,
470            std::cmp::Ordering::Equal => {
471                self.parent[ry] = rx;
472                self.rank[rx] += 1;
473            }
474        }
475        self.count -= 1;
476        true
477    }
478    /// Return `true` if `x` and `y` are in the same set.
479    pub fn connected(&mut self, x: usize, y: usize) -> bool {
480        self.find(x) == self.find(y)
481    }
482    /// Return the number of disjoint sets.
483    pub fn num_sets(&self) -> usize {
484        self.count
485    }
486}
487#[allow(dead_code)]
488#[derive(Debug, Clone)]
489pub struct PersistentSegmentTree {
490    pub n: usize,
491    pub num_versions: usize,
492    pub root_per_version: Vec<usize>,
493    pub nodes: Vec<(i64, usize, usize)>,
494}
495#[allow(dead_code)]
496impl PersistentSegmentTree {
497    pub fn new(n: usize) -> Self {
498        PersistentSegmentTree {
499            n,
500            num_versions: 0,
501            root_per_version: vec![],
502            nodes: vec![(0, 0, 0)],
503        }
504    }
505    pub fn space_complexity(&self) -> String {
506        format!(
507            "Persistent SegTree: O(n + q log n) nodes for {} versions",
508            self.num_versions
509        )
510    }
511    pub fn time_complexity(&self) -> String {
512        format!(
513            "O(log {}) per query/update, supports historical queries",
514            self.n
515        )
516    }
517    pub fn range_query_version(&self, version: usize, _l: usize, _r: usize) -> i64 {
518        let _ = version;
519        0
520    }
521}
522/// Fenwick tree (Binary Indexed Tree).
523#[allow(dead_code)]
524#[derive(Debug, Clone)]
525pub struct FenwickTree {
526    tree: Vec<i64>,
527}
528impl FenwickTree {
529    #[allow(dead_code)]
530    pub fn new(n: usize) -> Self {
531        Self {
532            tree: vec![0i64; n + 1],
533        }
534    }
535    #[allow(dead_code)]
536    pub fn update(&mut self, mut i: usize, delta: i64) {
537        while i < self.tree.len() {
538            self.tree[i] += delta;
539            i += i & i.wrapping_neg();
540        }
541    }
542    #[allow(dead_code)]
543    pub fn prefix_sum(&self, mut i: usize) -> i64 {
544        let mut s = 0i64;
545        while i > 0 {
546            s += self.tree[i];
547            i -= i & i.wrapping_neg();
548        }
549        s
550    }
551    #[allow(dead_code)]
552    pub fn range_sum(&self, l: usize, r: usize) -> i64 {
553        if l == 0 {
554            self.prefix_sum(r)
555        } else {
556            self.prefix_sum(r) - self.prefix_sum(l - 1)
557        }
558    }
559}
560/// An AVL self-balancing binary search tree.
561///
562/// All operations (insert, contains) run in O(log n) worst-case time.
563/// The height is always ≤ 1.44 * log2(n + 2).
564pub struct AvlTree<T: Ord> {
565    root: Option<Box<AvlNode<T>>>,
566    size: usize,
567}
568impl<T: Ord> AvlTree<T> {
569    /// Create a new empty AVL tree.
570    pub fn new() -> Self {
571        AvlTree {
572            root: None,
573            size: 0,
574        }
575    }
576    /// Insert a value into the tree.
577    ///
578    /// Duplicate values are ignored.
579    /// Time complexity: O(log n).
580    pub fn insert(&mut self, value: T) {
581        let old_root = self.root.take();
582        let new_root = avl_insert(old_root, value);
583        self.size += 1;
584        self.root = Some(new_root);
585    }
586    /// Return `true` if `value` is in the tree.
587    ///
588    /// Time complexity: O(log n).
589    pub fn contains(&self, value: &T) -> bool {
590        avl_contains(&self.root, value)
591    }
592    /// Return the height of the tree (0 for an empty tree).
593    pub fn height(&self) -> usize {
594        avl_height(&self.root)
595    }
596    /// Return the number of elements in the tree.
597    pub fn len(&self) -> usize {
598        self.size
599    }
600    /// Return `true` if the tree contains no elements.
601    pub fn is_empty(&self) -> bool {
602        self.size == 0
603    }
604}
605/// A probabilistic Bloom filter with configurable number of bits and hash functions.
606pub struct BloomFilterDs {
607    /// Bit vector.
608    bits: Vec<bool>,
609    /// Number of hash functions k.
610    k: usize,
611    /// Number of bits m.
612    m: usize,
613    /// Number of inserted elements.
614    count: usize,
615}
616impl BloomFilterDs {
617    /// Construct a Bloom filter with `m` bits and `k` hash functions.
618    pub fn new(m: usize, k: usize) -> Self {
619        BloomFilterDs {
620            bits: vec![false; m.max(1)],
621            k,
622            m: m.max(1),
623            count: 0,
624        }
625    }
626    /// Compute the j-th hash of a key (using FNV-derived mixing).
627    fn hash(&self, key: u64, j: usize) -> usize {
628        let h = key
629            .wrapping_mul(0x9e3779b97f4a7c15_u64)
630            .wrapping_add((j as u64).wrapping_mul(0x6c62272e07bb0142_u64));
631        (h >> 33) as usize % self.m
632    }
633    /// Insert a key into the Bloom filter.
634    pub fn insert(&mut self, key: u64) {
635        for j in 0..self.k {
636            let idx = self.hash(key, j);
637            self.bits[idx] = true;
638        }
639        self.count += 1;
640    }
641    /// Query whether a key may be present. Returns false iff definitely absent.
642    pub fn might_contain(&self, key: u64) -> bool {
643        (0..self.k).all(|j| self.bits[self.hash(key, j)])
644    }
645    /// Approximate false positive probability: (1 - e^{-kn/m})^k.
646    pub fn false_positive_rate(&self) -> f64 {
647        let exp = -(self.k as f64 * self.count as f64) / self.m as f64;
648        (1.0 - exp.exp()).powi(self.k as i32)
649    }
650    /// Number of elements inserted.
651    pub fn len(&self) -> usize {
652        self.count
653    }
654    /// Whether the filter has had any insertions.
655    pub fn is_empty(&self) -> bool {
656        self.count == 0
657    }
658}
659/// A node in an AVL tree.
660pub struct AvlNode<T: Ord> {
661    pub value: T,
662    pub height: usize,
663    pub left: Option<Box<AvlNode<T>>>,
664    pub right: Option<Box<AvlNode<T>>>,
665}
666impl<T: Ord> AvlNode<T> {
667    pub(super) fn new(value: T) -> Box<Self> {
668        Box::new(AvlNode {
669            value,
670            height: 1,
671            left: None,
672            right: None,
673        })
674    }
675}
676/// A segment tree supporting range sum queries and point updates.
677///
678/// Both `query` and `update` run in O(log n) time.
679pub struct SegmentTree {
680    n: usize,
681    data: Vec<i64>,
682}
683impl SegmentTree {
684    /// Build a segment tree from a slice of values.
685    ///
686    /// Time complexity: O(n).
687    pub fn new(values: &[i64]) -> Self {
688        let n = values.len();
689        let mut data = vec![0i64; 4 * n.max(1)];
690        if n > 0 {
691            Self::build(&mut data, values, 0, 0, n - 1);
692        }
693        SegmentTree { n, data }
694    }
695    fn build(data: &mut Vec<i64>, values: &[i64], node: usize, start: usize, end: usize) {
696        if start == end {
697            data[node] = values[start];
698        } else {
699            let mid = (start + end) / 2;
700            Self::build(data, values, 2 * node + 1, start, mid);
701            Self::build(data, values, 2 * node + 2, mid + 1, end);
702            data[node] = data[2 * node + 1] + data[2 * node + 2];
703        }
704    }
705    /// Query the sum over the index range `[l, r]` (inclusive).
706    ///
707    /// Returns `0` for an empty range or out-of-bounds query.
708    /// Time complexity: O(log n).
709    pub fn query(&self, l: usize, r: usize) -> i64 {
710        if self.n == 0 || l > r || r >= self.n {
711            return 0;
712        }
713        self.query_inner(0, 0, self.n - 1, l, r)
714    }
715    fn query_inner(&self, node: usize, start: usize, end: usize, l: usize, r: usize) -> i64 {
716        if r < start || end < l {
717            return 0;
718        }
719        if l <= start && end <= r {
720            return self.data[node];
721        }
722        let mid = (start + end) / 2;
723        self.query_inner(2 * node + 1, start, mid, l, r)
724            + self.query_inner(2 * node + 2, mid + 1, end, l, r)
725    }
726    /// Update the element at index `idx` to `value`.
727    ///
728    /// Time complexity: O(log n).
729    pub fn update(&mut self, idx: usize, value: i64) {
730        if idx >= self.n {
731            return;
732        }
733        self.update_inner(0, 0, self.n - 1, idx, value);
734    }
735    fn update_inner(&mut self, node: usize, start: usize, end: usize, idx: usize, value: i64) {
736        if start == end {
737            self.data[node] = value;
738        } else {
739            let mid = (start + end) / 2;
740            if idx <= mid {
741                self.update_inner(2 * node + 1, start, mid, idx, value);
742            } else {
743                self.update_inner(2 * node + 2, mid + 1, end, idx, value);
744            }
745            self.data[node] = self.data[2 * node + 1] + self.data[2 * node + 2];
746        }
747    }
748    /// Return the number of leaf elements in the tree.
749    pub fn len(&self) -> usize {
750        self.n
751    }
752    /// Return `true` if the tree has no elements.
753    pub fn is_empty(&self) -> bool {
754        self.n == 0
755    }
756}
757/// A trie (prefix tree) storing strings of bytes.
758///
759/// Supports `insert` and `search` in O(|key|) time.
760pub struct Trie {
761    nodes: Vec<TrieNode>,
762}
763impl Trie {
764    /// Create a new empty trie.
765    pub fn new() -> Self {
766        Trie {
767            nodes: vec![TrieNode::new()],
768        }
769    }
770    /// Insert a string into the trie.
771    ///
772    /// Time complexity: O(|key|).
773    pub fn insert(&mut self, key: &str) {
774        let mut current = 0;
775        for byte in key.bytes() {
776            let idx = byte as usize;
777            if self.nodes[current].children[idx].is_none() {
778                let new_node = self.nodes.len();
779                self.nodes.push(TrieNode::new());
780                self.nodes[current].children[idx] = Some(new_node);
781            }
782            current = self.nodes[current].children[idx]
783                .expect("children[idx] is Some: was just inserted in the if branch above");
784        }
785        self.nodes[current].is_terminal = true;
786    }
787    /// Return `true` if `key` was previously inserted into the trie.
788    ///
789    /// Time complexity: O(|key|).
790    pub fn search(&self, key: &str) -> bool {
791        let mut current = 0;
792        for byte in key.bytes() {
793            let idx = byte as usize;
794            match self.nodes[current].children[idx] {
795                None => return false,
796                Some(next) => current = next,
797            }
798        }
799        self.nodes[current].is_terminal
800    }
801    /// Return `true` if any key in the trie starts with `prefix`.
802    ///
803    /// Time complexity: O(|prefix|).
804    pub fn starts_with(&self, prefix: &str) -> bool {
805        let mut current = 0;
806        for byte in prefix.bytes() {
807            let idx = byte as usize;
808            match self.nodes[current].children[idx] {
809                None => return false,
810                Some(next) => current = next,
811            }
812        }
813        true
814    }
815}
816/// A probabilistic skip list with O(log n) expected insert and search.
817///
818/// Implementation note: uses a simple Vec-based implementation (no raw pointers).
819///
820/// This implementation uses a Vec-of-Vecs structure (no unsafe pointers).
821/// Each element is stored in the base level; higher levels hold express lanes.
822pub struct SkipList<T: Ord + Clone> {
823    /// Levels of sorted vectors; `levels[0]` is the base (all elements).
824    levels: Vec<Vec<T>>,
825    max_levels: usize,
826    /// Simple deterministic "random" source for level generation.
827    counter: u64,
828}
829impl<T: Ord + Clone> SkipList<T> {
830    /// Create a new empty skip list with the given maximum number of levels.
831    pub fn new(max_levels: usize) -> Self {
832        let max_levels = max_levels.max(1);
833        SkipList {
834            levels: vec![Vec::new(); max_levels],
835            max_levels,
836            counter: 0,
837        }
838    }
839    /// Return the number of elements in the skip list (base level size).
840    pub fn len(&self) -> usize {
841        self.levels[0].len()
842    }
843    /// Return `true` if the skip list is empty.
844    pub fn is_empty(&self) -> bool {
845        self.levels[0].is_empty()
846    }
847    /// Determine how many levels to promote a newly inserted element to.
848    ///
849    /// Uses a simple linear-congruential generator as a deterministic stand-in
850    /// for the usual coin-flip; real skip lists use a random source.
851    fn random_level(&mut self) -> usize {
852        self.counter = self
853            .counter
854            .wrapping_mul(6364136223846793005)
855            .wrapping_add(1442695040888963407);
856        let mut level = 1;
857        let mut bits = self.counter;
858        while level < self.max_levels && (bits & 1) == 0 {
859            level += 1;
860            bits >>= 1;
861        }
862        level
863    }
864    /// Insert `value` into the skip list.
865    ///
866    /// Expected time complexity: O(log n).
867    pub fn insert(&mut self, value: T) {
868        let num_levels = self.random_level();
869        for level in 0..num_levels {
870            let pos = self.levels[level].partition_point(|x| x < &value);
871            if pos >= self.levels[level].len() || self.levels[level][pos] != value {
872                self.levels[level].insert(pos, value.clone());
873            }
874        }
875    }
876    /// Return `true` if `value` is in the skip list.
877    ///
878    /// Uses the highest occupied level for fast scanning.
879    /// Expected time complexity: O(log n).
880    pub fn contains(&self, value: &T) -> bool {
881        for level in (0..self.max_levels).rev() {
882            if self.levels[level].is_empty() {
883                continue;
884            }
885            if self.levels[level].binary_search(value).is_ok() {
886                return true;
887            }
888        }
889        false
890    }
891}
892/// A node in the character-trie.
893struct TrieNode {
894    children: Vec<Option<usize>>,
895    is_terminal: bool,
896}
897impl TrieNode {
898    fn new() -> Self {
899        TrieNode {
900            children: vec![None; TRIE_ALPHABET],
901            is_terminal: false,
902        }
903    }
904}
905/// A double-ended queue backed by two `Vec`s.
906///
907/// Elements pushed to the front go into `front` (reversed),
908/// elements pushed to the back go into `back`.
909/// All four operations (`push_front`, `push_back`, `pop_front`, `pop_back`)
910/// are amortized O(1).
911pub struct Deque<T> {
912    front: Vec<T>,
913    back: Vec<T>,
914}
915impl<T> Deque<T> {
916    /// Create a new empty deque.
917    pub fn new() -> Self {
918        Deque {
919            front: Vec::new(),
920            back: Vec::new(),
921        }
922    }
923    /// Return the number of elements in the deque.
924    pub fn len(&self) -> usize {
925        self.front.len() + self.back.len()
926    }
927    /// Return `true` if the deque is empty.
928    pub fn is_empty(&self) -> bool {
929        self.front.is_empty() && self.back.is_empty()
930    }
931    /// Push `value` to the front of the deque.
932    pub fn push_front(&mut self, value: T) {
933        self.front.push(value);
934    }
935    /// Push `value` to the back of the deque.
936    pub fn push_back(&mut self, value: T) {
937        self.back.push(value);
938    }
939    /// Remove and return the front element, or `None` if empty.
940    pub fn pop_front(&mut self) -> Option<T> {
941        if let Some(v) = self.front.pop() {
942            return Some(v);
943        }
944        if self.back.is_empty() {
945            return None;
946        }
947        let len = self.back.len();
948        if len == 1 {
949            return self.back.pop();
950        }
951        let keep = (len + 1) / 2;
952        let mut moved = self.back.split_off(keep);
953        moved.reverse();
954        self.front = moved;
955        self.front.pop()
956    }
957    /// Remove and return the back element, or `None` if empty.
958    pub fn pop_back(&mut self) -> Option<T> {
959        if let Some(v) = self.back.pop() {
960            return Some(v);
961        }
962        if self.front.is_empty() {
963            return None;
964        }
965        let len = self.front.len();
966        if len == 1 {
967            return self.front.pop();
968        }
969        let keep = (len + 1) / 2;
970        let mut moved = self.front.split_off(keep);
971        moved.reverse();
972        self.back = moved;
973        self.back.pop()
974    }
975    /// Return a reference to the front element, or `None` if empty.
976    pub fn front(&self) -> Option<&T> {
977        self.front.last().or_else(|| self.back.first())
978    }
979    /// Return a reference to the back element, or `None` if empty.
980    pub fn back(&self) -> Option<&T> {
981        self.back.last().or_else(|| self.front.first())
982    }
983}
984/// HyperLogLog cardinality estimator.
985///
986/// Uses b-bit register index (2^b registers) to estimate set cardinality
987/// with relative error approximately 1.04 / sqrt(2^b).
988pub struct HyperLogLog {
989    /// Number of register index bits.
990    b: u32,
991    /// The registers M[0..m).
992    registers: Vec<u8>,
993    /// m = 2^b.
994    m: usize,
995}
996impl HyperLogLog {
997    /// Construct a HyperLogLog estimator with 2^b registers.
998    pub fn new(b: u32) -> Self {
999        let b = b.clamp(4, 16);
1000        let m = 1usize << b;
1001        HyperLogLog {
1002            b,
1003            registers: vec![0u8; m],
1004            m,
1005        }
1006    }
1007    /// Hash a u64 key using FNV-1a mixing.
1008    fn hash_key(&self, key: u64) -> u64 {
1009        key.wrapping_mul(0x517cc1b727220a95_u64)
1010            .rotate_left(17)
1011            .wrapping_mul(0x6c62272e07bb0142_u64)
1012    }
1013    /// Add an element to the estimator.
1014    pub fn add(&mut self, key: u64) {
1015        let h = self.hash_key(key);
1016        let index = (h >> (64 - self.b)) as usize;
1017        let w = h << self.b;
1018        let rho = if w == 0 {
1019            (64 - self.b) as u8 + 1
1020        } else {
1021            w.trailing_zeros() as u8 + 1
1022        };
1023        if rho > self.registers[index] {
1024            self.registers[index] = rho;
1025        }
1026    }
1027    /// Estimate the cardinality using the HyperLogLog formula.
1028    pub fn estimate(&self) -> f64 {
1029        let m = self.m as f64;
1030        let alpha = 0.7213 / (1.0 + 1.079 / m);
1031        let z: f64 = self.registers.iter().map(|&r| 2f64.powi(-(r as i32))).sum();
1032        let raw = alpha * m * m / z;
1033        if raw <= 2.5 * m {
1034            let zeros = self.registers.iter().filter(|&&r| r == 0).count() as f64;
1035            if zeros > 0.0 {
1036                m * (m / zeros).ln()
1037            } else {
1038                raw
1039            }
1040        } else {
1041            raw
1042        }
1043    }
1044    /// Relative error bound: ~1.04 / sqrt(m).
1045    pub fn relative_error_bound(&self) -> f64 {
1046        1.04 / (self.m as f64).sqrt()
1047    }
1048    /// Number of registers.
1049    pub fn num_registers(&self) -> usize {
1050        self.m
1051    }
1052}
1053/// B-tree properties.
1054#[allow(dead_code)]
1055#[derive(Debug, Clone)]
1056pub struct BTree {
1057    pub order: usize,
1058    pub num_keys: usize,
1059    pub height: usize,
1060}
1061impl BTree {
1062    #[allow(dead_code)]
1063    pub fn new(order: usize) -> Self {
1064        Self {
1065            order,
1066            num_keys: 0,
1067            height: 0,
1068        }
1069    }
1070    #[allow(dead_code)]
1071    pub fn max_keys_per_node(&self) -> usize {
1072        2 * self.order - 1
1073    }
1074    #[allow(dead_code)]
1075    pub fn min_keys_per_node(&self) -> usize {
1076        self.order - 1
1077    }
1078    #[allow(dead_code)]
1079    pub fn max_height_for_n_keys(&self, n: usize) -> usize {
1080        if n <= 1 {
1081            return 0;
1082        }
1083        let t = self.order;
1084        ((n + 1) as f64 / 2.0).log(t as f64).ceil() as usize
1085    }
1086    #[allow(dead_code)]
1087    pub fn disk_access_per_operation(&self) -> String {
1088        format!("O(log_t(n)) disk accesses, t={}", self.order)
1089    }
1090}
1091/// Union-Find (Disjoint Set Union) data structure.
1092#[allow(dead_code)]
1093#[derive(Debug, Clone)]
1094pub struct UnionFind {
1095    parent: Vec<usize>,
1096    rank: Vec<usize>,
1097    num_components: usize,
1098}
1099impl UnionFind {
1100    #[allow(dead_code)]
1101    pub fn new(n: usize) -> Self {
1102        Self {
1103            parent: (0..n).collect(),
1104            rank: vec![0; n],
1105            num_components: n,
1106        }
1107    }
1108    #[allow(dead_code)]
1109    pub fn find(&mut self, x: usize) -> usize {
1110        if self.parent[x] != x {
1111            self.parent[x] = self.find(self.parent[x]);
1112        }
1113        self.parent[x]
1114    }
1115    #[allow(dead_code)]
1116    pub fn union(&mut self, x: usize, y: usize) -> bool {
1117        let rx = self.find(x);
1118        let ry = self.find(y);
1119        if rx == ry {
1120            return false;
1121        }
1122        if self.rank[rx] < self.rank[ry] {
1123            self.parent[rx] = ry;
1124        } else if self.rank[rx] > self.rank[ry] {
1125            self.parent[ry] = rx;
1126        } else {
1127            self.parent[ry] = rx;
1128            self.rank[rx] += 1;
1129        }
1130        self.num_components -= 1;
1131        true
1132    }
1133    #[allow(dead_code)]
1134    pub fn connected(&mut self, x: usize, y: usize) -> bool {
1135        self.find(x) == self.find(y)
1136    }
1137    #[allow(dead_code)]
1138    pub fn num_components(&self) -> usize {
1139        self.num_components
1140    }
1141}
1142/// Binary min-heap.
1143#[allow(dead_code)]
1144#[derive(Debug, Clone)]
1145pub struct BinaryMinHeap<T: Ord + Clone> {
1146    data: Vec<T>,
1147}
1148impl<T: Ord + Clone> BinaryMinHeap<T> {
1149    #[allow(dead_code)]
1150    pub fn new() -> Self {
1151        Self { data: Vec::new() }
1152    }
1153    #[allow(dead_code)]
1154    pub fn push(&mut self, val: T) {
1155        self.data.push(val);
1156        self.sift_up(self.data.len() - 1);
1157    }
1158    #[allow(dead_code)]
1159    pub fn pop(&mut self) -> Option<T> {
1160        if self.data.is_empty() {
1161            return None;
1162        }
1163        let n = self.data.len();
1164        self.data.swap(0, n - 1);
1165        let val = self.data.pop();
1166        if !self.data.is_empty() {
1167            self.sift_down(0);
1168        }
1169        val
1170    }
1171    #[allow(dead_code)]
1172    pub fn peek(&self) -> Option<&T> {
1173        self.data.first()
1174    }
1175    #[allow(dead_code)]
1176    pub fn len(&self) -> usize {
1177        self.data.len()
1178    }
1179    #[allow(dead_code)]
1180    pub fn is_empty(&self) -> bool {
1181        self.data.is_empty()
1182    }
1183    fn sift_up(&mut self, mut i: usize) {
1184        while i > 0 {
1185            let parent = (i - 1) / 2;
1186            if self.data[i] < self.data[parent] {
1187                self.data.swap(i, parent);
1188                i = parent;
1189            } else {
1190                break;
1191            }
1192        }
1193    }
1194    fn sift_down(&mut self, mut i: usize) {
1195        let n = self.data.len();
1196        loop {
1197            let left = 2 * i + 1;
1198            let right = 2 * i + 2;
1199            let mut smallest = i;
1200            if left < n && self.data[left] < self.data[smallest] {
1201                smallest = left;
1202            }
1203            if right < n && self.data[right] < self.data[smallest] {
1204                smallest = right;
1205            }
1206            if smallest != i {
1207                self.data.swap(i, smallest);
1208                i = smallest;
1209            } else {
1210                break;
1211            }
1212        }
1213    }
1214}
1215/// Disjoint hash map (open addressing).
1216#[allow(dead_code)]
1217#[derive(Debug, Clone)]
1218pub struct SimpleHashMap {
1219    buckets: Vec<Option<(u64, u64)>>,
1220    size: usize,
1221    capacity: usize,
1222}
1223impl SimpleHashMap {
1224    #[allow(dead_code)]
1225    pub fn new(capacity: usize) -> Self {
1226        Self {
1227            buckets: vec![None; capacity],
1228            size: 0,
1229            capacity,
1230        }
1231    }
1232    fn hash(&self, key: u64) -> usize {
1233        (key as usize).wrapping_mul(2654435769) % self.capacity
1234    }
1235    #[allow(dead_code)]
1236    pub fn insert(&mut self, key: u64, val: u64) {
1237        let mut h = self.hash(key);
1238        loop {
1239            match self.buckets[h] {
1240                None => {
1241                    self.buckets[h] = Some((key, val));
1242                    self.size += 1;
1243                    return;
1244                }
1245                Some((k, _)) if k == key => {
1246                    self.buckets[h] = Some((key, val));
1247                    return;
1248                }
1249                _ => {
1250                    h = (h + 1) % self.capacity;
1251                }
1252            }
1253        }
1254    }
1255    #[allow(dead_code)]
1256    pub fn get(&self, key: u64) -> Option<u64> {
1257        let mut h = self.hash(key);
1258        for _ in 0..self.capacity {
1259            match self.buckets[h] {
1260                None => return None,
1261                Some((k, v)) if k == key => return Some(v),
1262                _ => h = (h + 1) % self.capacity,
1263            }
1264        }
1265        None
1266    }
1267    #[allow(dead_code)]
1268    pub fn load_factor(&self) -> f64 {
1269        self.size as f64 / self.capacity as f64
1270    }
1271}
1272/// Skip list (probabilistic data structure).
1273#[allow(dead_code)]
1274#[derive(Debug, Clone)]
1275pub struct SkipListInfo {
1276    pub num_levels: usize,
1277    pub promotion_probability: f64,
1278    pub expected_space: f64,
1279}
1280impl SkipListInfo {
1281    #[allow(dead_code)]
1282    pub fn new(n: usize, p: f64) -> Self {
1283        let max_levels = (n as f64).log2().ceil() as usize + 1;
1284        let expected_space = n as f64 / (1.0 - p);
1285        Self {
1286            num_levels: max_levels,
1287            promotion_probability: p,
1288            expected_space,
1289        }
1290    }
1291    #[allow(dead_code)]
1292    pub fn expected_search_time_description(&self) -> String {
1293        format!(
1294            "Skip list with p={}: expected O(log n) search, O(n/1-p) space",
1295            self.promotion_probability
1296        )
1297    }
1298}
1299/// Persistent data structure (functional).
1300#[allow(dead_code)]
1301#[derive(Debug, Clone)]
1302pub struct PersistArrayOld<T: Clone> {
1303    versions: Vec<Vec<T>>,
1304}
1305impl<T: Clone> PersistArrayOld<T> {
1306    #[allow(dead_code)]
1307    pub fn new(initial: Vec<T>) -> Self {
1308        Self {
1309            versions: vec![initial],
1310        }
1311    }
1312    #[allow(dead_code)]
1313    pub fn current_version(&self) -> usize {
1314        self.versions.len() - 1
1315    }
1316    #[allow(dead_code)]
1317    pub fn update(&mut self, version: usize, idx: usize, val: T) -> usize {
1318        let mut new_v = self.versions[version].clone();
1319        if idx < new_v.len() {
1320            new_v[idx] = val;
1321        }
1322        self.versions.push(new_v);
1323        self.versions.len() - 1
1324    }
1325    #[allow(dead_code)]
1326    pub fn get(&self, version: usize, idx: usize) -> Option<&T> {
1327        self.versions.get(version)?.get(idx)
1328    }
1329}
1330
1331/// Type alias for `PersistArrayOld` - a persistent array with version tracking.
1332pub type PersistArrayExt<T> = PersistArrayOld<T>;
1333
1334#[allow(dead_code)]
1335#[derive(Debug, Clone)]
1336pub struct VanEmdeBoasTree {
1337    pub universe_size: usize,
1338    pub min: Option<usize>,
1339    pub max: Option<usize>,
1340    pub summary: Option<Box<VanEmdeBoasTree>>,
1341}
1342#[allow(dead_code)]
1343impl VanEmdeBoasTree {
1344    pub fn new(universe: usize) -> Self {
1345        VanEmdeBoasTree {
1346            universe_size: universe,
1347            min: None,
1348            max: None,
1349            summary: if universe > 2 {
1350                let sqrt = (universe as f64).sqrt().ceil() as usize;
1351                Some(Box::new(VanEmdeBoasTree::new(sqrt)))
1352            } else {
1353                None
1354            },
1355        }
1356    }
1357    pub fn complexity_description(&self) -> String {
1358        format!(
1359            "van Emde Boas: insert/delete/predecessor in O(log log U) where U={}",
1360            self.universe_size
1361        )
1362    }
1363    pub fn is_empty(&self) -> bool {
1364        self.min.is_none()
1365    }
1366    pub fn upper_sqrt(&self) -> usize {
1367        (self.universe_size as f64).sqrt().ceil() as usize
1368    }
1369    pub fn lower_sqrt(&self) -> usize {
1370        (self.universe_size as f64).sqrt().floor() as usize
1371    }
1372    pub fn high(&self, x: usize) -> usize {
1373        x / self.lower_sqrt()
1374    }
1375    pub fn low(&self, x: usize) -> usize {
1376        x % self.lower_sqrt()
1377    }
1378}
1379#[allow(dead_code)]
1380#[derive(Debug, Clone)]
1381pub struct XFastTrie {
1382    pub universe_bits: usize,
1383    pub levels: Vec<std::collections::HashMap<usize, String>>,
1384    pub num_elements: usize,
1385}
1386#[allow(dead_code)]
1387impl XFastTrie {
1388    pub fn new(bits: usize) -> Self {
1389        XFastTrie {
1390            universe_bits: bits,
1391            levels: vec![std::collections::HashMap::new(); bits + 1],
1392            num_elements: 0,
1393        }
1394    }
1395    pub fn complexity_description(&self) -> String {
1396        format!(
1397            "X-Fast Trie: O(log W) search, O(W) space (W={} bits)",
1398            self.universe_bits
1399        )
1400    }
1401    pub fn predecessor_time(&self) -> String {
1402        format!(
1403            "O(log W) = O(log {}) per predecessor query",
1404            self.universe_bits
1405        )
1406    }
1407}
1408#[allow(dead_code)]
1409#[derive(Debug, Clone)]
1410pub struct PersistArrayV2<T: Clone> {
1411    pub data: Vec<T>,
1412    pub versions: Vec<(usize, T)>,
1413    pub current_version: usize,
1414}
1415#[allow(dead_code)]
1416impl<T: Clone + Default> PersistArrayV2<T> {
1417    pub fn new(size: usize) -> Self {
1418        PersistArrayV2 {
1419            data: vec![T::default(); size],
1420            versions: vec![],
1421            current_version: 0,
1422        }
1423    }
1424    pub fn update(&mut self, idx: usize, val: T) -> usize {
1425        let old = self.data[idx].clone();
1426        self.versions.push((idx, old));
1427        self.data[idx] = val;
1428        self.current_version += 1;
1429        self.current_version
1430    }
1431    pub fn rollback(&mut self) {
1432        if let Some((idx, old_val)) = self.versions.pop() {
1433            self.data[idx] = old_val;
1434            self.current_version = self.current_version.saturating_sub(1);
1435        }
1436    }
1437    pub fn complexity(&self) -> String {
1438        format!(
1439            "PersistentArray: O(1) update/rollback (path copying), {} versions stored",
1440            self.versions.len()
1441        )
1442    }
1443}