haar_lib/ds/
foldable_deque.rs1pub use crate::algebra::traits::*;
3
4#[derive(Clone, Default, Debug)]
5pub struct FoldableDeque<S: Semigroup> {
7 front_stack: Vec<S>,
8 back_stack: Vec<S>,
9 front_sum: Vec<S>,
10 back_sum: Vec<S>,
11}
12
13impl<S: Semigroup + Clone> FoldableDeque<S> {
14 pub fn new() -> Self {
16 FoldableDeque {
17 front_stack: vec![],
18 back_stack: vec![],
19 front_sum: vec![],
20 back_sum: vec![],
21 }
22 }
23
24 fn f(&self, a: Option<S>, b: Option<S>) -> Option<S> {
25 match (a, b) {
26 (Some(a), Some(b)) => Some(S::op(a, b)),
27 (x, None) => x,
28 (None, x) => x,
29 }
30 }
31
32 pub fn fold(&self) -> Option<S> {
34 self.f(
35 self.front_sum.last().cloned(),
36 self.back_sum.last().cloned(),
37 )
38 }
39
40 pub fn push_back(&mut self, value: S) {
42 self.back_stack.push(value.clone());
43 self.back_sum
44 .push(self.f(self.back_sum.last().cloned(), Some(value)).unwrap());
45 }
46
47 pub fn push_front(&mut self, value: S) {
49 self.front_stack.push(value.clone());
50 self.front_sum
51 .push(self.f(Some(value), self.front_sum.last().cloned()).unwrap());
52 }
53
54 fn build_sum(&mut self) {
55 for value in &self.front_stack {
56 self.front_sum.push(
57 self.f(Some(value.clone()), self.front_sum.last().cloned())
58 .unwrap(),
59 );
60 }
61
62 for value in &self.back_stack {
63 self.back_sum.push(
64 self.f(self.back_sum.last().cloned(), Some(value.clone()))
65 .unwrap(),
66 );
67 }
68 }
69
70 pub fn pop_front(&mut self) -> Option<S> {
72 if self.front_stack.is_empty() {
73 self.back_sum.clear();
74
75 let n = self.back_stack.len();
76 if n == 0 {
77 return None;
78 }
79
80 self.front_stack = self.back_stack.split_off(n.div_ceil(2));
81 std::mem::swap(&mut self.front_stack, &mut self.back_stack);
82 self.front_stack.reverse();
83
84 self.build_sum();
85 }
86
87 self.front_sum.pop();
88 self.front_stack.pop()
89 }
90
91 pub fn pop_back(&mut self) -> Option<S> {
93 if self.back_stack.is_empty() {
94 self.front_sum.clear();
95
96 let n = self.front_stack.len();
97 if n == 0 {
98 return None;
99 }
100
101 self.back_stack = self.front_stack.split_off(n.div_ceil(2));
102 std::mem::swap(&mut self.front_stack, &mut self.back_stack);
103 self.back_stack.reverse();
104
105 self.build_sum();
106 }
107
108 self.back_sum.pop();
109 self.back_stack.pop()
110 }
111
112 pub fn front(&self) -> Option<&S> {
114 self.front_stack.last().or_else(|| self.back_stack.first())
115 }
116
117 pub fn back(&self) -> Option<&S> {
119 self.back_stack.last().or_else(|| self.front_stack.first())
120 }
121
122 pub fn len(&self) -> usize {
124 self.front_stack.len() + self.back_stack.len()
125 }
126
127 pub fn is_empty(&self) -> bool {
129 self.front_stack.is_empty() && self.back_stack.is_empty()
130 }
131}
132
133#[cfg(test)]
134mod tests {
135 use super::*;
136 use crate::{algebra::affine::*, num::const_modint::ConstModInt};
137 use rand::Rng;
138 use std::collections::VecDeque;
139
140 const M: u32 = 998244353;
141 type Mint = ConstModInt<M>;
142
143 #[test]
144 fn test() {
145 let mut rng = rand::thread_rng();
146
147 let mut deq = VecDeque::<Affine<Mint>>::new();
148 let mut swag = FoldableDeque::<Affine<Mint>>::new();
149
150 for _ in 0..1000 {
151 assert_eq!(deq.front(), swag.front());
152 assert_eq!(deq.back(), swag.back());
153 assert_eq!(deq.len(), swag.len());
154
155 let ty = rng.gen_range(0..5);
156
157 match ty {
158 0 => {
159 let a = Mint::new(rng.gen_range(0..M));
160 let b = Mint::new(rng.gen_range(0..M));
161 deq.push_front(Affine(a, b));
162 swag.push_front(Affine(a, b));
163 }
164 1 => {
165 let a = Mint::new(rng.gen_range(0..M));
166 let b = Mint::new(rng.gen_range(0..M));
167 deq.push_back(Affine(a, b));
168 swag.push_back(Affine(a, b));
169 }
170 2 => {
171 assert_eq!(deq.pop_front(), swag.pop_front());
172 }
173 3 => {
174 assert_eq!(deq.pop_back(), swag.pop_back());
175 }
176 4 => {
177 assert_eq!(
178 deq.iter().cloned().fold_m(),
179 swag.fold().unwrap_or(Affine::id())
180 );
181 }
182 _ => unreachable!(),
183 }
184 }
185 }
186}