struct ConcaveEnvelope<'a, T> {
arbitrary: &'a [T],
concave: &'a [T],
leaf_count: usize,
query_root: usize,
node_curves: Vec<Option<usize>>,
result: Vec<T>,
}Fields§
§arbitrary: &'a [T]§concave: &'a [T]§leaf_count: usize§query_root: usize§node_curves: Vec<Option<usize>>§result: Vec<T>Implementations§
Source§impl<'a, T> ConcaveEnvelope<'a, T>where
T: Signed,
impl<'a, T> ConcaveEnvelope<'a, T>where
T: Signed,
Sourcefn new(arbitrary: &'a [T], concave: &'a [T]) -> Self
fn new(arbitrary: &'a [T], concave: &'a [T]) -> Self
Examples found in repository?
crates/competitive/src/math/min_plus_convolution/concave.rs (line 205)
181pub(super) fn concave_envelope<T>(arbitrary: &[T], concave: &[T]) -> Vec<T>
182where
183 T: Signed,
184{
185 if concave.len() == 1 {
186 return arbitrary
187 .iter()
188 .map(|&value| {
189 if value.is_maximum() {
190 T::maximum()
191 } else {
192 value + concave[0]
193 }
194 })
195 .collect();
196 }
197 if arbitrary.len() == 1 {
198 return if arbitrary[0].is_maximum() {
199 vec![T::maximum(); concave.len()]
200 } else {
201 concave.iter().map(|&value| arbitrary[0] + value).collect()
202 };
203 }
204
205 ConcaveEnvelope::new(arbitrary, concave).convolve()
206}Sourcefn value(&self, curve: usize, output: usize) -> T
fn value(&self, curve: usize, output: usize) -> T
Examples found in repository?
crates/competitive/src/math/min_plus_convolution/concave.rs (line 55)
50 fn query(&mut self, output: usize) {
51 let mut best = self.result[output];
52 let mut node = (output + self.leaf_count) >> 1;
53 while node >= self.query_root {
54 if let Some(curve) = self.node_curves[node] {
55 best = best.min(self.value(curve, output));
56 }
57 node >>= 1;
58 }
59 self.result[output] = best;
60 }
61
62 #[inline]
63 fn insert_from_left(&mut self, left: usize) {
64 let mut right = left + self.concave.len();
65 let block = 1_usize << (left ^ right).ilog2();
66 right &= !(block - 1);
67 let mut depth = bit_width(right - left - 1);
68 let mut node = (self.leaf_count + left) >> depth;
69 let mut pending = (!self.arbitrary[left].is_maximum()).then_some(left);
70 while depth != 0 {
71 let Some(curve) = pending else {
72 break;
73 };
74 depth -= 1;
75 let middle = ((node << 1 | 1) << depth) - self.leaf_count - 1;
76 if middle < left {
77 node = node << 1 | 1;
78 } else if self.node_curves[node]
79 .is_some_and(|old| self.value(old, middle) < self.value(curve, middle))
80 {
81 node <<= 1;
82 } else {
83 std::mem::swap(&mut self.node_curves[node], &mut pending);
84 node = node << 1 | 1;
85 }
86 }
87 if let Some(curve) = pending {
88 let output = node - self.leaf_count;
89 self.result[output] = self.result[output].min(self.value(curve, output));
90 }
91 }
92
93 #[inline]
94 fn insert_from_right(&mut self, right: usize) {
95 let curve = right - self.concave.len();
96 let block = 1_usize << (curve ^ right).ilog2();
97 let left = right & !(block - 1);
98 if left == right {
99 return;
100 }
101 let mut depth = bit_width(right - left - 1);
102 let mut node = (self.leaf_count + left) >> depth;
103 let mut pending = (!self.arbitrary[curve].is_maximum()).then_some(curve);
104 while depth != 0 {
105 let Some(curve) = pending else {
106 break;
107 };
108 depth -= 1;
109 let middle = ((node << 1 | 1) << depth) - self.leaf_count;
110 if middle >= right {
111 node <<= 1;
112 } else if self.node_curves[node]
113 .is_some_and(|old| self.value(old, middle) < self.value(curve, middle))
114 {
115 node = node << 1 | 1;
116 } else {
117 std::mem::swap(&mut self.node_curves[node], &mut pending);
118 node <<= 1;
119 }
120 }
121 if let Some(curve) = pending {
122 let output = node - self.leaf_count;
123 self.result[output] = self.result[output].min(self.value(curve, output));
124 }
125 }Sourcefn query(&mut self, output: usize)
fn query(&mut self, output: usize)
Examples found in repository?
crates/competitive/src/math/min_plus_convolution/concave.rs (line 132)
127 fn convolve(mut self) -> Vec<T> {
128 // Curve i is valid on [i, i + concave.len()). The two passes insert
129 // opposite sides of each validity interval into the segment envelope.
130 for left in 0..self.arbitrary.len() {
131 self.insert_from_left(left);
132 self.query(left);
133 }
134 for output in self.arbitrary.len()..self.result.len() {
135 self.query(output);
136 }
137
138 self.node_curves.fill(None);
139 let mut right = self.result.len();
140 while right >= self.concave.len() {
141 self.insert_from_right(right);
142 right -= 1;
143 self.query(right);
144 }
145 for output in 0..self.concave.len() {
146 self.query(output);
147 }
148 self.result
149 }Sourcefn insert_from_left(&mut self, left: usize)
fn insert_from_left(&mut self, left: usize)
Examples found in repository?
crates/competitive/src/math/min_plus_convolution/concave.rs (line 131)
127 fn convolve(mut self) -> Vec<T> {
128 // Curve i is valid on [i, i + concave.len()). The two passes insert
129 // opposite sides of each validity interval into the segment envelope.
130 for left in 0..self.arbitrary.len() {
131 self.insert_from_left(left);
132 self.query(left);
133 }
134 for output in self.arbitrary.len()..self.result.len() {
135 self.query(output);
136 }
137
138 self.node_curves.fill(None);
139 let mut right = self.result.len();
140 while right >= self.concave.len() {
141 self.insert_from_right(right);
142 right -= 1;
143 self.query(right);
144 }
145 for output in 0..self.concave.len() {
146 self.query(output);
147 }
148 self.result
149 }Sourcefn insert_from_right(&mut self, right: usize)
fn insert_from_right(&mut self, right: usize)
Examples found in repository?
crates/competitive/src/math/min_plus_convolution/concave.rs (line 141)
127 fn convolve(mut self) -> Vec<T> {
128 // Curve i is valid on [i, i + concave.len()). The two passes insert
129 // opposite sides of each validity interval into the segment envelope.
130 for left in 0..self.arbitrary.len() {
131 self.insert_from_left(left);
132 self.query(left);
133 }
134 for output in self.arbitrary.len()..self.result.len() {
135 self.query(output);
136 }
137
138 self.node_curves.fill(None);
139 let mut right = self.result.len();
140 while right >= self.concave.len() {
141 self.insert_from_right(right);
142 right -= 1;
143 self.query(right);
144 }
145 for output in 0..self.concave.len() {
146 self.query(output);
147 }
148 self.result
149 }Sourcefn convolve(self) -> Vec<T>
fn convolve(self) -> Vec<T>
Examples found in repository?
crates/competitive/src/math/min_plus_convolution/concave.rs (line 205)
181pub(super) fn concave_envelope<T>(arbitrary: &[T], concave: &[T]) -> Vec<T>
182where
183 T: Signed,
184{
185 if concave.len() == 1 {
186 return arbitrary
187 .iter()
188 .map(|&value| {
189 if value.is_maximum() {
190 T::maximum()
191 } else {
192 value + concave[0]
193 }
194 })
195 .collect();
196 }
197 if arbitrary.len() == 1 {
198 return if arbitrary[0].is_maximum() {
199 vec![T::maximum(); concave.len()]
200 } else {
201 concave.iter().map(|&value| arbitrary[0] + value).collect()
202 };
203 }
204
205 ConcaveEnvelope::new(arbitrary, concave).convolve()
206}Auto Trait Implementations§
impl<'a, T> Freeze for ConcaveEnvelope<'a, T>
impl<'a, T> RefUnwindSafe for ConcaveEnvelope<'a, T>
impl<'a, T> Send for ConcaveEnvelope<'a, T>
impl<'a, T> Sync for ConcaveEnvelope<'a, T>
impl<'a, T> Unpin for ConcaveEnvelope<'a, T>
impl<'a, T> UnsafeUnpin for ConcaveEnvelope<'a, T>
impl<'a, T> UnwindSafe for ConcaveEnvelope<'a, T>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more