1use std::cell::RefCell;
4use std::ops::Add;
5use std::rc::{Rc, Weak};
6
7enum Reduce<T, F, W> {
8 Reduce0E,
9 Reduce1E(Reduce1<T, F, W>),
10 Reduce2E(Reduce2<T, F, W>),
11}
12use Reduce::{Reduce0E, Reduce1E, Reduce2E};
13
14struct Fetcher<T, F, W> {
15 dp: RefCell<Vec<Option<T>>>,
16 map: F,
17 trans: W,
18}
19
20struct Reduce1<T, F, W> {
21 n: usize,
22 i: usize,
23 j0: usize,
24 j1: usize,
25 reduce: Box<Reduce<T, F, W>>,
26 row_shift: u32,
27 col_map: RefCell<Vec<usize>>,
28 c: RefCell<Vec<usize>>,
29 fetcher: Weak<RefCell<Fetcher<T, F, W>>>,
30}
31
32struct Reduce2<T, F, W> {
33 n: usize,
34 i: usize,
35 j: usize,
36 srow: Vec<usize>,
37 scol: Vec<usize>,
38 reduce: Box<Reduce<T, F, W>>,
39 row_shift: u32,
40 col_map: RefCell<Vec<usize>>,
41 c: RefCell<Vec<usize>>,
42 fetcher: Weak<RefCell<Fetcher<T, F, W>>>,
43}
44
45pub struct Larsch<T, F, W> {
121 n: usize,
122 reduce: Box<Reduce<T, F, W>>,
123 fetcher: Rc<RefCell<Fetcher<T, F, W>>>,
124}
125
126impl<T, F, W> Reduce<T, F, W>
127where
128 F: Fn(&T) -> T,
129 W: Fn(usize, usize) -> T,
130 T: Add<Output = T> + Ord,
131{
132 fn new(
133 n: usize,
134 m: usize,
135 row_shift: u32,
136 col_map: &[usize],
137 fetcher: Weak<RefCell<Fetcher<T, F, W>>>,
138 ) -> Self {
139 if n == 0 && m == 1 {
140 Reduce0E
141 } else if n >= m {
142 Reduce1E(Reduce1::new(n, m, row_shift, col_map, fetcher))
143 } else {
144 Reduce2E(Reduce2::new(n, m, row_shift, col_map, fetcher))
145 }
146 }
147
148 fn next(&mut self) -> Option<usize> {
149 match self {
150 Reduce0E => None,
151 Reduce1E(r) => r.next(),
152 Reduce2E(r) => r.next(),
153 }
154 }
155
156 fn set_col_map(&mut self, i_par: usize, i_child: usize) {
157 match self {
158 Reduce0E => {}
159 Reduce1E(r) => r.set_col_map(i_par, i_child),
160 Reduce2E(r) => r.set_col_map(i_par, i_child),
161 }
162 }
163
164 fn set_c(&mut self, i: usize, j: usize) {
165 match self {
166 Reduce0E => {}
167 Reduce1E(r) => r.set_c(i, j),
168 Reduce2E(r) => r.set_c(i, j),
169 }
170 }
171}
172
173impl<T, F, W> Fetcher<T, F, W>
174where
175 F: Fn(&T) -> T,
176 W: Fn(usize, usize) -> T,
177 T: Add<Output = T> + Ord,
178{
179 fn new(dp: Vec<Option<T>>, map: F, trans: W) -> Self {
180 let dp = RefCell::new(dp);
181 Self { dp, map, trans }
182 }
183
184 fn fetch(&self, i: usize, j: usize) -> T {
185 let f = (self.map)(self.dp.borrow()[j].as_ref().unwrap());
186 let w = (self.trans)(j, i);
187 let res = f + w;
188 res
189 }
190
191 fn set(&self, i: usize, val: T) { self.dp.borrow_mut()[i] = Some(val); }
192
193 fn finish(self) -> Vec<T> {
194 self.dp.into_inner().into_iter().map(Option::unwrap).collect()
195 }
196}
197
198impl<T, F, W> Larsch<T, F, W>
199where
200 F: Fn(&T) -> T,
201 W: Fn(usize, usize) -> T,
202 T: Add<Output = T> + Ord,
203{
204 pub fn new(n: usize, m: usize, init: T, map: F, trans: W) -> Self {
205 let dp: Vec<_> = (0..=n).map(|_| None).collect();
206 let fetcher = Fetcher::new(dp, map, trans);
207 fetcher.set(0, init);
208 let fetcher = Rc::new(RefCell::new(fetcher));
209 let row_shift = 0;
210 let col_map: Vec<_> = (0..m).collect();
211 let reduce =
212 Reduce::new(n, m, row_shift, &col_map, Rc::downgrade(&fetcher));
213 Self { n, reduce: Box::new(reduce), fetcher }
214 }
215
216 pub fn solve(mut self) -> (Vec<usize>, Vec<T>) {
217 let mut argmin = vec![0; self.n + 1];
218 for i in 1..=self.n {
219 self.reduce.set_c(i, i - 1);
220 argmin[i] = self.reduce.next().unwrap();
221 let x = self.fetcher.borrow().fetch(i, argmin[i]);
222 self.fetcher.borrow().set(i, x);
223 }
224
225 let dp: Vec<_> =
226 Rc::try_unwrap(self.fetcher).ok().unwrap().into_inner().finish();
227
228 (argmin, dp)
229 }
230}
231
232impl<T, F, W> Reduce1<T, F, W>
233where
234 F: Fn(&T) -> T,
235 W: Fn(usize, usize) -> T,
236 T: Add<Output = T> + Ord,
237{
238 fn new(
239 n: usize,
240 m: usize,
241 row_shift: u32,
242 col_map: &[usize],
243 fetcher: Weak<RefCell<Fetcher<T, F, W>>>,
244 ) -> Self {
245 let reduce = Reduce::new(
246 n / 2,
247 m,
248 row_shift + 1,
249 col_map,
250 Weak::clone(&fetcher),
251 );
252
253 Self {
254 n,
255 i: 1,
256 j0: 0,
257 j1: 0,
258 reduce: Box::new(reduce),
259 row_shift,
260 col_map: RefCell::new(col_map.to_vec()),
261 c: RefCell::new(vec![0; n + 1]),
262 fetcher,
263 }
264 }
265
266 fn c(&self, i: usize) -> usize { self.c.borrow()[i] }
267
268 fn set_col_map(&mut self, i_par: usize, i_child: usize) {
269 self.col_map.borrow_mut()[i_child] = i_par;
270 self.reduce.set_col_map(i_par, i_child);
271 }
272
273 fn set_c(&mut self, i: usize, j: usize) {
274 self.c.borrow_mut()[i] = j;
275 if i / 2 + 1 <= self.n / 2 {
276 self.reduce.set_c(i / 2 + 1, j);
277 }
278 }
279
280 fn fetch(&self, i: usize, j: usize) -> T {
281 let i = i << self.row_shift;
282 let j = self.col_map.borrow()[j];
283 self.fetcher.upgrade().unwrap().borrow().fetch(i, j)
284 }
285
286 fn next(&mut self) -> Option<usize> {
287 if self.i > self.n {
288 return None;
289 }
290
291 let j_range = if self.i % 2 == 1 {
292 if self.i % 2 == 1 && self.i / 2 + 1 <= self.n / 2 {
293 self.reduce.set_c(self.i / 2 + 1, self.c(self.i));
294 }
295 self.j1 = self.reduce.next().unwrap_or_else(|| self.c(self.i));
296 (self.j0..=self.j1).chain(None)
297 } else {
298 (self.c(self.i - 1) + 1..=self.c(self.i)).chain(Some(self.j1))
299 };
300
301 let j = j_range.min_by_key(|&j| (self.fetch(self.i, j), j)).unwrap();
302 if self.i % 2 == 0 {
303 self.j0 = j;
304 }
305
306 self.i += 1;
307 Some(j)
308 }
309}
310
311impl<T, F, W> Reduce2<T, F, W>
312where
313 F: Fn(&T) -> T,
314 W: Fn(usize, usize) -> T,
315 T: Add<Output = T> + Ord,
316{
317 fn new(
318 n: usize,
319 _m: usize,
320 row_shift: u32,
321 col_map: &[usize],
322 fetcher: Weak<RefCell<Fetcher<T, F, W>>>,
323 ) -> Self {
324 let reduce =
325 Reduce::new(n, n, row_shift, &vec![0; n], Weak::clone(&fetcher));
326
327 Self {
328 n,
329 i: 1,
330 j: 0,
331 srow: vec![0],
332 scol: vec![0],
333 reduce: Box::new(reduce),
334 row_shift,
335 col_map: RefCell::new(col_map.to_vec()),
336 c: RefCell::new(vec![0; n + 1]),
337 fetcher,
338 }
339 }
340
341 fn c(&self, i: usize) -> usize { self.c.borrow()[i] }
342
343 fn is_finite(&self, i: usize, j: usize) -> bool {
344 j <= self.c(i.min(self.i))
345 }
346
347 fn set_col_map(&mut self, i_par: usize, i_child: usize) {
348 self.col_map.borrow_mut()[i_child] = i_par;
349 }
350
351 fn set_c(&mut self, i: usize, j: usize) { self.c.borrow_mut()[i] = j; }
352
353 fn fetch(&self, i: usize, j: usize) -> Option<T> {
354 if !self.is_finite(i, j) {
355 return None;
356 }
357
358 let i = i << self.row_shift;
359 let j = self.col_map.borrow()[j];
360
361 Some(self.fetcher.upgrade().unwrap().borrow().fetch(i, j))
362 }
363
364 fn is_lt(
365 &self,
366 (il, jl): (usize, usize),
367 (ir, jr): (usize, usize),
368 ) -> bool {
369 if (il, jl) == (ir, jr) {
370 return false;
371 }
372 match (self.fetch(il, jl), self.fetch(ir, jr)) {
373 (Some(fl), Some(fr)) => (fl, jl) < (fr, jr),
374 (_, None) => true, (None, _) => false, }
377 }
378
379 fn next(&mut self) -> Option<usize> {
380 if self.i > self.n {
381 return None;
382 }
383
384 let jl = if self.i == 1 { 0 } else { self.c(self.i - 1) + 1 };
386 let jr = self.c(self.i);
387 for j in jl..=jr {
388 loop {
389 let r = *self.srow.last().unwrap();
390 let c = *self.scol.last().unwrap();
391 if !self.is_lt((r, j), (r, c)) {
392 break;
393 }
394 self.srow.pop();
395 self.scol.pop();
396 }
397 if *self.srow.last().unwrap() < self.n {
398 let r = *self.srow.last().unwrap();
399 let i_ = (r + 1..).find(|&i_| self.is_finite(i_, j)).unwrap();
400 self.srow.push(i_);
401 self.scol.push(j);
402 }
403 }
404 if self.j + 1 < self.srow.len() && self.srow[self.j + 1] == self.i {
405 self.j += 1;
406 let tmp = self.col_map.borrow()[self.scol[self.j]];
407 self.reduce.set_col_map(tmp, self.j - 1);
408 }
409
410 self.reduce.set_c(self.i, self.j - 1);
411 let j = self.reduce.next().unwrap();
412 self.i += 1;
413 Some(self.scol[j + 1])
414 }
415}