competitive_library/structure/
skew_heap_lazy.rs1use std::mem::swap;
4#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
5pub struct Heap<T: Clone> {
6 pub cost: i64,
7 pub value: T,
8 pub lazy: Option<i64>,
9 pub left: Option<Box<Heap<T>>>,
10 pub right: Option<Box<Heap<T>>>,
11}
12
13impl<T: Clone> Heap<T> {
14 pub fn new(cost: i64, value: T) -> Option<Box<Heap<T>>> {
15 Some(Box::new(Heap {
16 cost,
17 value,
18 lazy: None,
19 left: None,
20 right: None,
21 }))
22 }
23}
24#[derive(Default, Clone)]
25pub struct SkewHeap<T: Clone> {
26 node: Option<Box<Heap<T>>>,
27}
28impl<T: Clone> SkewHeap<T> {
29 pub fn new() -> Self {
30 Self { node: None }
31 }
32
33 #[inline]
34 pub fn push(&mut self, cost: i64, value: T) {
35 SkewHeap::merge(&mut self.node, Heap::new(cost, value));
36 }
37 #[inline]
38 pub fn top(&self) -> Option<(i64, T)> {
39 Some((self.node.as_ref()?.cost, self.node.as_ref()?.value.clone()))
40 }
41 #[inline]
42 pub fn pop(&mut self) -> Option<(i64, T)> {
43 Self::propagate(&mut self.node);
44 let value = self.top()?;
45
46 let (mut left, right) = {
47 let mut tmp = self.node.take().unwrap();
48 (tmp.left.take(), tmp.right.take())
49 };
50 SkewHeap::merge(&mut left, right);
51 swap(&mut self.node, &mut left);
52
53 Some(value)
54 }
55
56 #[inline]
57 pub fn merge(a: &mut Option<Box<Heap<T>>>, mut b: Option<Box<Heap<T>>>) {
58 if a.is_none() {
59 swap(a, &mut b);
60 return;
61 }
62 if b.is_none() {
63 return;
64 }
65 Self::propagate(a);
66 Self::propagate(&mut b);
67
68 if a.as_ref().unwrap().cost > b.as_ref().unwrap().cost {
69 swap(a, &mut b);
70 }
71 SkewHeap::merge(&mut a.as_mut().unwrap().right, b);
72
73 let tmp = a.as_mut().unwrap();
74 swap(&mut tmp.left, &mut tmp.right);
75 }
76
77 #[inline]
78 pub fn add(&mut self, value: i64) {
79 self.node.as_mut().unwrap().lazy = Some(value);
80 Self::propagate(&mut self.node);
81 }
82 #[inline]
83 fn propagate(node: &mut Option<Box<Heap<T>>>) {
84 if let Some(n) = node.as_mut() {
85 if n.lazy.is_none() {
86 return;
87 }
88 if let Some(l) = n.left.as_mut() {
89 l.lazy = n.lazy;
90 }
91 if let Some(r) = n.right.as_mut() {
92 r.lazy = n.lazy;
93 }
94
95 n.cost += n.lazy.unwrap();
96 n.lazy = None;
97 }
98 }
99}
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104 #[test]
105 fn test_heap() {
106 let mut a = vec![SkewHeap::new(); 5];
107
108 for i in 0..30 {
109 a[i % 5].push(i as i64, 0);
110 }
111
112 for (i, e) in a.iter().enumerate() {
113 assert_eq!(e.top().unwrap().0, i as i64);
114 }
115
116 for i in 1..5 {
117 let buff = a[i].node.take();
118 SkewHeap::merge(&mut a[0].node, buff);
119 }
120
121 for i in 0..15 {
122 assert_eq!(a[0].pop().unwrap().0, i);
123 }
124 a[0].add(5);
125 for i in 15..30 {
126 assert_eq!(a[0].pop().unwrap().0, i + 5);
127 }
128 }
129}