Guest User

V6

a guest
Sep 28th, 2026
75
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 5.63 KB | None | 0 0
  1. use std::ops::Range;
  2. use std::time::Instant;
  3.  
  4. use crate::algo_lib::collections::array_2d::Array2D;
  5.  
  6. use crate::algo_lib::io::input::Input;
  7. use crate::algo_lib::io::output::Output;
  8. use crate::algo_lib::misc::rand::Random;
  9.  
  10. #[target_feature(enable = "avx2")]
  11. fn solve_case(a: &[i32], queries: &[Range<usize>], k: usize) -> Vec<i32> {
  12.     let q = queries.len();
  13.     let mut res = vec![i32::MIN; q];
  14.     let mut dp_left = Array2D::new(0, a.len() / 10 + 10, k + 1);
  15.     loop {
  16.         let mut min_r = usize::MAX;
  17.         for i in 0..q {
  18.             if res[i] == i32::MIN {
  19.                 min_r = min_r.min(queries[i].end);
  20.             }
  21.         }
  22.         if min_r == usize::MAX {
  23.             break;
  24.         }
  25.         let mid = min_r;
  26.         let mut max_r = mid;
  27.         let mut min_l = usize::MAX;
  28.         for i in 0..q {
  29.             if res[i] == i32::MIN && queries[i].start < mid {
  30.                 max_r = max_r.max(queries[i].end);
  31.                 min_l = min_l.min(queries[i].start);
  32.             }
  33.         }
  34.  
  35.         let mut by_right = vec![];
  36.         for i in 0..q {
  37.             if res[i] != i32::MIN || queries[i].start >= mid {
  38.                 continue;
  39.             }
  40.             let right_len = queries[i].end - mid;
  41.             by_right.push((right_len, i, queries[i].start));
  42.         }
  43.         by_right.sort_unstable();
  44.  
  45.         for use_center in 0..2 {
  46.             {
  47.                 // dp[len][segm_open?][cnt_used]
  48.                 let len = mid - min_l;
  49.  
  50.                 let mut dp = Array2D::new(i32::MIN / 2, 2, k + 1);
  51.                 let mut ndp = Array2D::new(i32::MIN / 2, 2, k + 1);
  52.  
  53.                 dp[use_center][0] = 0;
  54.                 for i in 0..len {
  55.                     let cur_val = a[mid - 1 - i];
  56.                     // end of segment
  57.                     update_dp(&mut ndp[1][1..], &dp[1][1..], &dp[0][..k], cur_val);
  58.                     ndp[1][0] = dp[1][0];
  59.                     // start new segment
  60.                     update_dp(&mut ndp[0], &dp[0], &dp[1], -cur_val);
  61.                     dp_left[i].copy_from_slice(&dp[0]);
  62.                     std::mem::swap(&mut dp, &mut ndp);
  63.                 }
  64.                 dp_left[len].copy_from_slice(&dp[0]);
  65.             };
  66.  
  67.             {
  68.                 // dp[len][segm_open?][cnt_used]
  69.                 let len = max_r - mid;
  70.                 let mut dp = Array2D::new(i32::MIN / 2, 2, k + 1);
  71.                 let mut ndp = Array2D::new(i32::MIN / 2, 2, k + 1);
  72.                 dp[use_center].fill(0);
  73.                 let mut q_it = 0;
  74.                 for i in 0..=len {
  75.                     while q_it < by_right.len() && by_right[q_it].0 == i {
  76.                         let (right_len, qid, qstart) = by_right[q_it];
  77.                         assert_eq!(right_len, i);
  78.                         q_it += 1;
  79.                         let left_len = mid - qstart;
  80.  
  81.                         let best = fast_conv(&dp_left[left_len], &dp[0]);
  82.  
  83.                         res[qid] = res[qid].max(best);
  84.                     }
  85.                     if i == len {
  86.                         break;
  87.                     }
  88.  
  89.                     let cur_val = a[mid + i];
  90.                     // open new segment
  91.                     update_dp(&mut ndp[1], &dp[1], &dp[0], -cur_val);
  92.                     // close segment
  93.                     update_dp(&mut ndp[0][1..], &dp[0][1..], &dp[1][..k], cur_val);
  94.  
  95.                     ndp[0][0] = dp[0][0];
  96.                     std::mem::swap(&mut dp, &mut ndp);
  97.                 }
  98.             };
  99.         }
  100.     }
  101.     res
  102. }
  103.  
  104. // ndp[i] = max(dp0[i], dp1[i] + cur_val)
  105. fn update_dp(ndp: &mut [i32], dp0: &[i32], dp1: &[i32], cur_val: i32) {
  106.     let k = dp0.len();
  107.     assert_eq!(ndp.len(), k);
  108.     assert_eq!(dp1.len(), k);
  109.     for j in 0..k {
  110.         ndp[j] = dp0[j].max(dp1[j] + cur_val);
  111.     }
  112. }
  113.  
  114. fn fast_conv(a: &[i32], b: &[i32]) -> i32 {
  115.     let mut res = i32::MIN;
  116.     let n = a.len();
  117.     assert_eq!(n, b.len());
  118.     for i in 0..n {
  119.         res = res.max(a[i] + b[n - 1 - i]);
  120.     }
  121.     res
  122. }
  123.  
  124. fn solve(input: &mut Input, out: &mut Output) {
  125.     let n = input.usize();
  126.     let k = input.usize();
  127.     let q = input.usize();
  128.     let mut a = input.vec::<i32>(n);
  129.     a.extend_from_slice(&a.clone());
  130.     let mut queries = vec![];
  131.     for _ in 0..q {
  132.         let l = input.usize() - 1;
  133.         let mut r = input.usize();
  134.         if l >= r {
  135.             r += n;
  136.         }
  137.         queries.push(l..r);
  138.     }
  139.     let res = unsafe { solve_case(&a, &queries, k) };
  140.     for &x in res.iter() {
  141.         out.println(x);
  142.     }
  143. }
  144.  
  145. fn stress() {
  146.     for it in 1.. {
  147.         dbg!(it);
  148.         let n = 100_000;
  149.         let q = 300_000;
  150.         let mut rnd = Random::new(it);
  151.         let mut a = rnd.gen_vec(n, 0..1_000_000);
  152.         a.extend_from_slice(&a.clone());
  153.         let mut queries = vec![];
  154.         for _ in 0..q {
  155.             let l = rnd.gen_range(0..n);
  156.             let fr = (0.15 * n as f64) as usize;
  157.             let to = (0.85 * n as f64) as usize;
  158.             let len = rnd.gen_range(fr..to);
  159.             let r = l + len;
  160.             queries.push(l..r);
  161.         }
  162.         let start = Instant::now();
  163.         let res = unsafe { solve_case(&a, &queries, 800) };
  164.         let res_xor = res.iter().fold(0, |acc, &x| acc ^ x);
  165.         dbg!(res_xor);
  166.         dbg!(start.elapsed());
  167.     }
  168. }
  169.  
  170. pub(crate) fn run(mut input: Input, mut output: Output) -> bool {
  171.     solve(&mut input, &mut output);
  172.     output.flush();
  173.     true
  174. }
  175.  
  176.  
  177. //END MAIN
  178.  
  179.  
  180. fn main() {
  181.     let input = crate::algo_lib::io::input::Input::new_stdin();
  182.     let mut output = crate::algo_lib::io::output::Output::new_stdout();
  183.     run(input, output);
  184. }
Advertisement
Add Comment
Please, Sign In to add comment