Skip to main content

ConcaveEnvelope

Struct ConcaveEnvelope 

Source
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,

Source

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}
Source

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    }
Source

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    }
Source

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    }
Source

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    }
Source

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>
where &'a [T]: Freeze, Vec<T>: Freeze,

§

impl<'a, T> RefUnwindSafe for ConcaveEnvelope<'a, T>

§

impl<'a, T> Send for ConcaveEnvelope<'a, T>
where &'a [T]: Send, Vec<T>: Send,

§

impl<'a, T> Sync for ConcaveEnvelope<'a, T>
where &'a [T]: Sync, Vec<T>: Sync,

§

impl<'a, T> Unpin for ConcaveEnvelope<'a, T>
where &'a [T]: Unpin, Vec<T>: Unpin,

§

impl<'a, T> UnsafeUnpin for ConcaveEnvelope<'a, T>
where &'a [T]: UnsafeUnpin, Vec<T>: UnsafeUnpin,

§

impl<'a, T> UnwindSafe for ConcaveEnvelope<'a, T>
where &'a [T]: UnwindSafe, Vec<T>: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToArrayVecScalar for T

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.