1use super::btree_bimap;
4
5use std::collections::BTreeMap;
6use std::fmt::{self, Debug};
7
8use btree_bimap::BTreeBimap;
9
10#[derive(Clone, Default)]
161pub struct IncrementalLineSet<I: Ord> {
162 f: BTreeMap<I, I>,
163 range: BTreeBimap<I, I>,
164}
165
166impl<I: ChtInt> IncrementalLineSet<I> {
167 pub fn new() -> Self { Self::default() }
168 pub fn push(&mut self, (a, b): (I, I)) {
169 if self.f.is_empty() {
170 let max = I::oo();
171 self.f.insert(a, b);
172 self.range.insert(a, max);
173 return;
174 }
175 if self.unused((a, b)) {
176 return;
177 }
178 self.remove_unused((a, b));
179 self.insert((a, b));
180 }
181 pub fn min(&self, x: I) -> Option<I> {
182 let a = *self.range.range_right(x..).next()?.1;
183 let b = self.f[&a];
184 Some(x.on_line((a, b)))
185 }
186 pub fn inner_len(&self) -> usize { self.f.len() }
187
188 fn unused(&self, (a, b): (I, I)) -> bool {
189 let (&al, &bl) = match self.f.range(a..).next() {
190 Some((&al, &bl)) if a == al => return bl <= b,
191 Some(s) => s,
192 None => return false,
193 };
194 let (&ar, &br) = match self.f.range(..a).next_back() {
195 Some(s) => s,
196 None => return false,
197 };
198 al.right(bl, (a, b)) >= a.right(b, (ar, br))
199 }
200 fn remove_unused(&mut self, (a, b): (I, I)) {
201 self.f.remove(&a);
202 self.range.remove_left(&a);
203
204 let mut rm = vec![];
205 for ((&all, &bll), (&al, &bl)) in
206 self.f.range(a..).skip(1).zip(self.f.range(a..))
207 {
208 if all.right(bll, (al, bl)) >= al.right(bl, (a, b)) {
209 rm.push(al);
210 } else {
211 break;
212 }
213 }
214 for ((&arr, &brr), (&ar, &br)) in
215 self.f.range(..a).rev().skip(1).zip(self.f.range(..a).rev())
216 {
217 if a.right(b, (ar, br)) >= ar.right(br, (arr, brr)) {
218 rm.push(ar);
219 } else {
220 break;
221 }
222 }
223 for ar in &rm {
224 self.f.remove(ar);
225 self.range.remove_left(ar);
226 }
227 }
228 fn insert(&mut self, (a, b): (I, I)) {
229 if let Some((&al, &bl)) = self.f.range(a..).next() {
230 self.range.insert(al, al.right(bl, (a, b)));
231 };
232 if let Some((&ar, &br)) = self.f.range(..a).next_back() {
233 self.range.insert(a, a.right(b, (ar, br)));
234 } else {
235 self.range.insert(a, I::oo());
236 }
237
238 self.f.insert(a, b);
239 }
240}
241
242struct LineDebugHelper<I>(I, I);
243
244impl<I: ChtInt> Debug for LineDebugHelper<I> {
245 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
246 let s = match (self.0.simplify(), self.1.simplify()) {
247 (0, _) => format!("\\x. {:?}", self.1),
248 (1, _) => format!("\\x. x{:+?}", self.1),
249 (-1, _) => format!("\\x. -x{:+?}", self.1),
250 (_, 0) => format!("\\x. {:?}x", self.0),
251 _ => format!("\\x. {:?}x{:+?}", self.0, self.1),
252 };
253 f.write_str(&s)
254 }
255}
256
257impl<I: ChtInt> Debug for IncrementalLineSet<I> {
258 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
259 f.debug_map()
260 .entries(
261 self.f
262 .iter()
263 .rev()
264 .zip(self.range.range_left(..).rev())
265 .map(|((&a, &b), (&_, &r))| (LineDebugHelper(a, b), ..=r)),
266 )
267 .finish()
268 }
269}
270
271pub trait ChtInt: Copy + Ord + Default + Debug {
272 fn oo() -> Self;
273 fn right(self, b: Self, line1: (Self, Self)) -> Self;
274 fn on_line(self, line: (Self, Self)) -> Self;
275 fn simplify(self) -> i8;
276}
277
278macro_rules! impl_cht_int {
279 ( $($tt:tt)* ) => { $(
280 impl ChtInt for $tt {
281 fn oo() -> $tt {
283 let w = (0 as $tt).count_zeros();
284 ((1 as $tt) << (w - 1)).wrapping_sub(1)
285 }
286 fn right(self, b: Self, (ar, br): (Self, Self)) -> Self {
287 let a = self;
289 (br - b).div_euclid(a - ar)
290 }
291 fn on_line(self, (a, b): (Self, Self)) -> Self { a * self + b }
292 fn simplify(self) -> i8 {
293 match self {
294 0 => 0,
295 1 => 1,
296 -1 => -1,
297 _ => 2,
298 }
299 }
300 }
301 )* };
302}
303
304impl_cht_int! { i8 i16 i32 i64 i128 isize }
305
306#[test]
307fn test_simple() {
308 let mut ls = IncrementalLineSet::new();
309 assert_eq!(ls.min(1), None);
310
311 let mut f = std::iter::successors(Some(185_i32), |&x| {
312 Some((x * 291 + 748) % 93739)
313 })
314 .map(|x| x % 300 - 150);
315
316 let mut naive = vec![];
317 for _ in 0..5000 {
318 let a = f.next().unwrap();
319 let b = f.next().unwrap();
320 ls.push((a, b));
321 naive.push((a, b));
322 for x in -100..=100 {
323 let expected = naive.iter().map(|&(a, b)| a * x + b).min();
324 let got = ls.min(x);
325 assert_eq!(got, expected);
326 }
327 }
328}
329
330#[test]
331fn test_cross() {
332 let mut ls = IncrementalLineSet::new();
334 ls.push((0, 0));
336 for a in 1..1000 {
337 ls.push((a, 0));
338 assert_eq!(ls.inner_len(), 2);
339 }
340 for a in 1..1000 {
341 ls.push((-a, 0));
342 assert_eq!(ls.inner_len(), 2);
343 }
344}
345
346#[test]
347fn test_many() {
348 let mut ls = IncrementalLineSet::new();
350 let mut y = 0;
352 let x_max = 1000;
353 for x in 0..=x_max {
354 let a = -x;
355 y += a;
356 ls.push((a, -a * x + y));
360 ls.push((-a, -a * x + y - a));
362 assert_eq!(ls.inner_len(), (2 * x + 1) as usize);
363 }
364 for x in -x_max..=x_max {
365 let y = -x * (x + 1) / 2;
366 assert_eq!(ls.min(x), Some(y));
367 }
368}
369
370#[test]
371fn test_frac() {
372 let mut ls = IncrementalLineSet::new();
374 ls.push((2, 1)); ls.push((-5, 6)); ls.push((0, 3)); assert_eq!(ls.inner_len(), 2);
378}
379
380#[test]
381fn test_below() {
382 let mut ls = IncrementalLineSet::new();
383 ls.push((0, 2));
384 assert_eq!(ls.min(10), Some(2));
385 ls.push((0, 4));
386 assert_eq!(ls.min(10), Some(2));
387 ls.push((0, 1));
388 assert_eq!(ls.min(10), Some(1));
389 assert_eq!(ls.inner_len(), 1);
390}
391
392#[cfg(test)]
393fn test_cf660_f_internal(a: &[i64], expected: i64) {
394 let n = a.len();
395 let sigma = {
396 let mut sigma = vec![0; n + 1];
397 for i in 0..n {
398 sigma[i + 1] = sigma[i] + a[i];
399 }
400 sigma
401 };
402 let tau = {
403 let mut tau = vec![0; n + 1];
404 for i in 0..n {
405 tau[i + 1] = tau[i] + a[i] * (i + 1) as i64;
406 }
407 tau
408 };
409 let p = |j: usize| tau[j] - j as i64 * sigma[j];
410 let q = |j: usize| j as i64;
411 let r = |i: usize| sigma[i];
412 let s = |i: usize| tau[i];
413
414 let mut ls = IncrementalLineSet::new();
415 let mut dp = vec![0; n + 1];
416 ls.push((q(0), p(0)));
417 for i in 1..=n {
418 dp[i] = -ls.min(r(i)).unwrap() + s(i);
419 ls.push((q(i), p(i)));
420 }
421 let actual = *dp.iter().max().unwrap();
422 assert_eq!(actual, expected);
423}
424
425#[test]
426fn test_cf660_f() {
427 test_cf660_f_internal(&[5, -1000, 1, -3, 7, -8], 16);
428 test_cf660_f_internal(&[1000, 1000, 1001, 1000, 1000], 15003);
429 test_cf660_f_internal(&[-60, -70, -80], 0);
430 test_cf660_f_internal(&[-4], 0);
431 test_cf660_f_internal(&[-3, 6], 9);
432 test_cf660_f_internal(&[8, 1, -6], 10);
433 test_cf660_f_internal(&[9, 2, -5, 1], 13);
434 test_cf660_f_internal(&[10, -3, -3, 8, 2], 37);
435 test_cf660_f_internal(&[3, 1, -9, 1, 2, -10], 5);
436 test_cf660_f_internal(&[-3, -7, -7, -9, -3, 7, -9], 11);
437 test_cf660_f_internal(&[-2, 1, -5, -2, 1, -9, 0, 2], 4);
438 test_cf660_f_internal(&[-1, 10, -8, -9, -7, 8, 6, -6, 7], 38);
439 test_cf660_f_internal(&[-9, -10, -9, 4, 6, 8, 3, -8, 0, 10], 100);
440 test_cf660_f_internal(
441 &[
442 349, -152, -35, -353, -647, -702, 64, 299, -431, -11, -185, 437,
443 237, -103, 1, 448, 23, -308, -689, 329, -409, 309, 424, -93, -192,
444 0, 257, -90, -394, -512, -148, 376, -394, -528, 212, -215, -255,
445 -684, -321, 503, -72, -227, -583, -537, -65, 444, -332, 465, -547,
446 291, -663, -235, 542, -89, -450, -212, 438, 12, 139, -558, -87,
447 433, -462, 79, 35,
448 ],
449 6676,
450 );
451 test_cf660_f_internal(&[7, -5, 3, -9, 8], 10);
452 test_cf660_f_internal(&[-7, 0, 10, 1, -1, -5, 6], 34);
453 test_cf660_f_internal(&[3, -10, -2, 5, 2, -7, 7], 21);
454 test_cf660_f_internal(&[0, -7, 1, -9], 1);
455 test_cf660_f_internal(&[4, -6, 3, 3], 13);
456 test_cf660_f_internal(&[-9, 8, 0, -4, -4, -3, -5, 9, -6, -9], 14);
457 test_cf660_f_internal(&[3, -5, -5, 1, -6, -2], 3);
458 test_cf660_f_internal(&[8, -2, -8, 4, -8, 8, -3, -8, 0], 12);
459 test_cf660_f_internal(&[3, 3, 0, -7, 6, -6], 11);
460 test_cf660_f_internal(&[5, -6, -2, 6, -2, -4, -3], 11);
461}