Skip to main content

devpage_design/prefix_sums/
mod.rs

1//! A sequence in key order that knows the summary of every prefix in log
2//! time: a treap whose every node holds the summary of its subtree. What a
3//! run keeps its children's sizes in, so a child's change of size, an insert
4//! before the first of 100,000 or a search for the child at a place along
5//! the run costs log time, and moves no sibling.
6
7use std::cmp::Ordering;
8
9/// What a stretch of items adds up to: `then` is the stretch followed by
10/// `next`, and `Default` is the empty stretch.
11pub trait Summary: Clone + Default {
12    fn then(&self, next: &Self) -> Self;
13}
14
15/// An item of a [`Sums`] and what it adds up to by itself.
16pub trait Item {
17    type Sum: Summary;
18    fn summary(&self) -> Self::Sum;
19}
20
21type Link = Option<u32>;
22
23struct Node<K, V: Item> {
24    key: K,
25    value: V,
26    priority: u64,
27    left: Link,
28    right: Link,
29    /// The summary of this subtree, in key order.
30    sum: V::Sum,
31    count: usize,
32}
33
34/// Items by key, each prefix's summary in log time.
35pub struct Sums<K, V: Item> {
36    nodes: Vec<Option<Node<K, V>>>,
37    free: Vec<u32>,
38    root: Link,
39    seed: u64,
40}
41
42impl<K: Ord + Clone, V: Item> Default for Sums<K, V> {
43    fn default() -> Self {
44        Sums::new()
45    }
46}
47
48impl<K: Ord + Clone, V: Item> Sums<K, V> {
49    pub fn new() -> Self {
50        Sums {
51            nodes: Vec::new(),
52            free: Vec::new(),
53            root: None,
54            seed: 0x9e37_79b9_7f4a_7c15,
55        }
56    }
57
58    pub fn len(&self) -> usize {
59        self.root.map_or(0, |r| self.node(r).count)
60    }
61
62    pub fn is_empty(&self) -> bool {
63        self.root.is_none()
64    }
65
66    /// The summary of every item.
67    pub fn total(&self) -> V::Sum {
68        self.sum(self.root)
69    }
70
71    pub fn get(&self, key: &K) -> Option<&V> {
72        let mut at = self.root;
73        while let Some(i) = at {
74            let n = self.node(i);
75            at = match key.cmp(&n.key) {
76                Ordering::Less => n.left,
77                Ordering::Greater => n.right,
78                Ordering::Equal => return Some(&n.value),
79            };
80        }
81        None
82    }
83
84    /// Puts `value` at `key`, replacing what was there; returns it.
85    pub fn insert(&mut self, key: K, value: V) -> Option<V> {
86        let old = self.remove(&key);
87        let (l, r) = self.split(self.root, &key, false);
88        let priority = self.next_priority();
89        let sum = value.summary();
90        let n = self.alloc(Node {
91            key,
92            value,
93            priority,
94            left: None,
95            right: None,
96            sum,
97            count: 1,
98        });
99        let m = self.merge(l, Some(n));
100        self.root = self.merge(m, r);
101        old
102    }
103
104    /// Takes the item at `key` out.
105    pub fn remove(&mut self, key: &K) -> Option<V> {
106        let (l, r) = self.split(self.root, key, false);
107        let (m, r) = self.split(r, key, true);
108        self.root = self.merge(l, r);
109        let m = m?;
110        let node = self.nodes[m as usize].take().expect("a live node");
111        self.free.push(m);
112        Some(node.value)
113    }
114
115    /// The summary of every item before `key`.
116    pub fn before(&self, key: &K) -> V::Sum {
117        let mut acc = V::Sum::default();
118        let mut at = self.root;
119        while let Some(i) = at {
120            let n = self.node(i);
121            if *key <= n.key {
122                at = n.left;
123            } else {
124                acc = acc.then(&self.sum(n.left)).then(&n.value.summary());
125                at = n.right;
126            }
127        }
128        acc
129    }
130
131    /// The first item whose prefix — the summary of it and everything before
132    /// it — `reaches`, which must be false and then true along the items;
133    /// with the summary of everything before it.
134    pub fn seek(&self, reaches: impl Fn(&V::Sum) -> bool) -> Option<(&K, &V, V::Sum)> {
135        let mut acc = V::Sum::default();
136        let mut at = self.root;
137        let mut found = None;
138        while let Some(i) = at {
139            let n = self.node(i);
140            let left = acc.then(&self.sum(n.left));
141            let with = left.then(&n.value.summary());
142            if reaches(&with) {
143                found = Some((&n.key, &n.value, left.clone()));
144                at = n.left;
145            } else {
146                acc = with;
147                at = n.right;
148            }
149        }
150        found
151    }
152
153    /// The items from `key` on, in order.
154    pub fn from<'a>(&'a self, key: &K) -> impl Iterator<Item = (&'a K, &'a V)> + 'a {
155        let mut stack = Vec::new();
156        let mut at = self.root;
157        while let Some(i) = at {
158            let n = self.node(i);
159            if n.key >= *key {
160                stack.push(i);
161                at = n.left;
162            } else {
163                at = n.right;
164            }
165        }
166        Walk { sums: self, stack }
167    }
168
169    /// Every item, in order.
170    pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
171        let mut stack = Vec::new();
172        let mut at = self.root;
173        while let Some(i) = at {
174            stack.push(i);
175            at = self.node(i).left;
176        }
177        Walk { sums: self, stack }
178    }
179
180    /// Every item, last first.
181    pub fn rev(&self) -> impl Iterator<Item = (&K, &V)> {
182        let mut stack = Vec::new();
183        let mut at = self.root;
184        while let Some(i) = at {
185            stack.push(i);
186            at = self.node(i).right;
187        }
188        Back { sums: self, stack }
189    }
190
191    fn node(&self, i: u32) -> &Node<K, V> {
192        self.nodes[i as usize].as_ref().expect("a live node")
193    }
194
195    fn node_mut(&mut self, i: u32) -> &mut Node<K, V> {
196        self.nodes[i as usize].as_mut().expect("a live node")
197    }
198
199    fn sum(&self, at: Link) -> V::Sum {
200        at.map_or_else(V::Sum::default, |i| self.node(i).sum.clone())
201    }
202
203    fn count(&self, at: Link) -> usize {
204        at.map_or(0, |i| self.node(i).count)
205    }
206
207    fn next_priority(&mut self) -> u64 {
208        // xorshift64*: priorities need only be unpredictable to the keys.
209        self.seed ^= self.seed >> 12;
210        self.seed ^= self.seed << 25;
211        self.seed ^= self.seed >> 27;
212        self.seed.wrapping_mul(0x2545_f491_4f6c_dd1d)
213    }
214
215    fn alloc(&mut self, node: Node<K, V>) -> u32 {
216        match self.free.pop() {
217            Some(i) => {
218                self.nodes[i as usize] = Some(node);
219                i
220            }
221            None => {
222                self.nodes.push(Some(node));
223                (self.nodes.len() - 1) as u32
224            }
225        }
226    }
227
228    fn fix(&mut self, i: u32) {
229        let (l, r) = {
230            let n = self.node(i);
231            (n.left, n.right)
232        };
233        let sum = self
234            .sum(l)
235            .then(&self.node(i).value.summary())
236            .then(&self.sum(r));
237        let count = self.count(l) + 1 + self.count(r);
238        let n = self.node_mut(i);
239        n.sum = sum;
240        n.count = count;
241    }
242
243    /// The subtree at `at` split into the keys before `key` and the rest —
244    /// or, `through`, the keys up to and including it and the rest.
245    fn split(&mut self, at: Link, key: &K, through: bool) -> (Link, Link) {
246        let Some(i) = at else {
247            return (None, None);
248        };
249        let goes_left = if through {
250            self.node(i).key <= *key
251        } else {
252            self.node(i).key < *key
253        };
254        if goes_left {
255            let right = self.node(i).right;
256            let (l, r) = self.split(right, key, through);
257            self.node_mut(i).right = l;
258            self.fix(i);
259            (Some(i), r)
260        } else {
261            let left = self.node(i).left;
262            let (l, r) = self.split(left, key, through);
263            self.node_mut(i).left = r;
264            self.fix(i);
265            (l, Some(i))
266        }
267    }
268
269    /// Two subtrees, every key of `a` before every key of `b`, as one.
270    fn merge(&mut self, a: Link, b: Link) -> Link {
271        match (a, b) {
272            (None, b) => b,
273            (a, None) => a,
274            (Some(x), Some(y)) => {
275                if self.node(x).priority > self.node(y).priority {
276                    let right = self.node(x).right;
277                    let m = self.merge(right, Some(y));
278                    self.node_mut(x).right = m;
279                    self.fix(x);
280                    Some(x)
281                } else {
282                    let left = self.node(y).left;
283                    let m = self.merge(Some(x), left);
284                    self.node_mut(y).left = m;
285                    self.fix(y);
286                    Some(y)
287                }
288            }
289        }
290    }
291}
292
293struct Walk<'a, K, V: Item> {
294    sums: &'a Sums<K, V>,
295    stack: Vec<u32>,
296}
297
298impl<'a, K: Ord + Clone, V: Item> Iterator for Walk<'a, K, V> {
299    type Item = (&'a K, &'a V);
300    fn next(&mut self) -> Option<Self::Item> {
301        let i = self.stack.pop()?;
302        let n = self.sums.node(i);
303        let mut at = n.right;
304        while let Some(j) = at {
305            self.stack.push(j);
306            at = self.sums.node(j).left;
307        }
308        Some((&n.key, &n.value))
309    }
310}
311
312struct Back<'a, K, V: Item> {
313    sums: &'a Sums<K, V>,
314    stack: Vec<u32>,
315}
316
317impl<'a, K: Ord + Clone, V: Item> Iterator for Back<'a, K, V> {
318    type Item = (&'a K, &'a V);
319    fn next(&mut self) -> Option<Self::Item> {
320        let i = self.stack.pop()?;
321        let n = self.sums.node(i);
322        let mut at = n.left;
323        while let Some(j) = at {
324            self.stack.push(j);
325            at = self.sums.node(j).right;
326        }
327        Some((&n.key, &n.value))
328    }
329}
330
331#[cfg(test)]
332mod tests;