Skip to main content

alpha_k

Function alpha_k 

Source
fn alpha_k(k: usize, n: usize) -> usize
Examples found in repository?
crates/competitive/src/data_structure/static_range_product.rs (line 170)
160    fn new(data: Vec<S::T>, level: usize) -> Self {
161        let n = data.len();
162        if n <= DIRECT_SIZE || level == 0 {
163            return Self::Direct { data };
164        }
165        if level == 1 {
166            return Self::Disjoint {
167                table: DisjointSparseTable::new(data),
168            };
169        }
170        let block_shift = scaled_block_shift(alpha_k(level - 1, n));
171        let block_size = 1usize << block_shift;
172        if block_size <= 1 || block_size >= n {
173            return Self::Direct { data };
174        }
175        let blocks = block_products::<S>(&data, block_size);
176        let between = Box::new(Self::new(blocks.products, level - 1));
177        Self::Recursive {
178            data,
179            block_shift,
180            prefix: blocks.prefix,
181            suffix: blocks.suffix,
182            between,
183        }
184    }
185
186    #[inline]
187    fn fold(&self, l: usize, r: usize) -> S::T {
188        match self {
189            Self::Direct { data } => fold_slice::<S>(data, l, r),
190            Self::Disjoint { table } => table.fold(l, r),
191            Self::Recursive {
192                data,
193                block_shift,
194                prefix,
195                suffix,
196                between,
197            } => {
198                let block_shift = *block_shift;
199                let bl = l >> block_shift;
200                let br = (r - 1) >> block_shift;
201                if bl == br {
202                    return fold_slice::<S>(data, l, r);
203                }
204                let mut res = suffix[l].clone();
205                if bl + 1 < br {
206                    let mid = between.fold(bl + 1, br);
207                    res = S::operate(&res, &mid);
208                }
209                S::operate(&res, &prefix[r - 1])
210            }
211        }
212    }
213}
214
215#[inline]
216fn fold_slice<S>(data: &[S::T], l: usize, r: usize) -> S::T
217where
218    S: SemiGroup,
219{
220    let mut res = data[l].clone();
221    for x in &data[l + 1..r] {
222        res = S::operate(&res, x);
223    }
224    res
225}
226
227fn block_products<S>(data: &[S::T], block_size: usize) -> BlockProducts<S::T>
228where
229    S: SemiGroup,
230{
231    let n = data.len();
232    let mut prefix = data.to_vec();
233    let mut suffix = data.to_vec();
234    let mut products = Vec::with_capacity(n.div_ceil(block_size));
235    for start in (0..n).step_by(block_size) {
236        let end = n.min(start + block_size);
237        for i in start + 1..end {
238            prefix[i] = S::operate(&prefix[i - 1], &data[i]);
239        }
240        for i in (start..end - 1).rev() {
241            suffix[i] = S::operate(&data[i], &suffix[i + 1]);
242        }
243        products.push(prefix[end - 1].clone());
244    }
245    BlockProducts {
246        prefix,
247        suffix,
248        products,
249    }
250}
251
252fn alpha_k(k: usize, n: usize) -> usize {
253    if k == 0 {
254        return n.div_ceil(2);
255    }
256    if n <= 1 {
257        return 0;
258    }
259    let mut x = n;
260    let mut c = 0;
261    while x > 1 {
262        x = alpha_k(k - 1, x);
263        c += 1;
264    }
265    c
266}
267
268fn inverse_ackermann(n: usize) -> usize {
269    let mut k = 0;
270    while alpha_k(k, n) > 3 {
271        k += 1;
272    }
273    k
274}