fn alpha_k(k: usize, n: usize) -> usizeExamples 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}