士兵 WC2025 & CTS2025

[WC2025] 士兵 & [CTS2025] 士兵

简单题,(还有抄袭环节)

题目链接: [WC2025] 士兵 和 [CTS2025] 士兵 。

题目描述:

有长度为 nn 的序列 a,ba,b ,一次操作中你可以任意指定区间 [l,r][l,r] 并令 [l,r][l,r] 内的 aa 全部 −1-1 。你可以进行任意次操作。设你进行了 kk 次操作,则这些操作的总权值为 (∑[ai≤0]bi)−km(\sum [a_i\le 0]b_i)-km ,你需要最大化权值。

n≤5×105,ai≤109,−109≤bi≤109n\le 5\times10^5,a_i\le 10^9,-10^9\le b_i\le 10^9 。

经典转化。首先将 [l,r][l,r] 的区间减法转化为差分数组上的 +/−+/- 。那么容易设计出 fi,jf_{i,j} 表示前 ii 个数,第 ii 个数的差分数组上的前缀和为 jj 的最大权值,则有:

fi,j=bi[ai≤j]+max⁡k{fi−1,k−m×max⁡{0,j−k}}f_{i,j}=b_i[a_i\le j]+\max_k\{f_{i-1,k}-m\times\max\{0,j-k\}\}

直接 DP 复杂度 O(nV)\mathcal{O}(nV) ,可以拿到 15%15\% 的分数。

这个 DP 的状态很显然有大量浪费。比如说一个小数据中 f1,100f_{1,100} 很显然是一个没有任何用处的状态,于是考虑离散化。

问题在于,我们究竟要离散化哪些值。所有的 aia_i 肯定要离散化的,然而这是错的。通过对拍我发现要离散化 ai−1a_i-1 。道理不难想,因为可能某一个 ii 的 bi=−109b_i=-10^9 ,但又必须把 ii 两边的值打下 00 ,所以必须把他控制在 11 。

这样复杂度就被优化为 O(n2)\mathcal{O}(n^2) ,可以获得 35%35\% 的分数。

再次观察 DP ,容易发现,对于 ii 的转移,差分数组上的 +/−+/- 只有可能在 j=aij=a_i 或 j=ai−1j=a_i-1 时发生,因为其他的在这里发生必然更劣。于是单次更新就只用更新 22 个点值,但仍然无济于事。

观察一下 DP 的转移,不妨把 max⁡\max 拆开为 j≤kj\le k 和 j>kj>k 两种情况:

Case #1: j≤kj\le k

此时比较简单,因为 fi,j=bi[ai≤j]+max⁡j≤kfi−1,kf_{i,j}=b_i[a_i\le j]+\max\limits_{j\le k}{f_{i-1,k}} ,这个直接线段树上区间加以及区间 max 即可解决。

Case #2: j>kj>k

此时有些复杂,因为 fi,j=bi[ai≤j]+max⁡j>kfi−1,k−m(j−k)f_{i,j}=b_i[a_i\le j]+\max\limits_{j> k}{f_{i-1,k}-m(j-k)} ,看起来很不可做。不过我们可以大便分离,得出 fi,j+mj=bi[ai≤j]+max⁡j>kfi−1,k+mkf_{i,j}+mj=b_i[a_i\le j]+\max\limits_{j> k}{f_{i-1,k}+mk} ,此时的形式恰好统一了!于是我们可以令 gi,j=fi,j+mjg_{i,j}=f_{i,j}+mj ,那么我们就可以在 gg 上得出和 Case #1 一样的转移,只需要维护区间加和区间 max 就行。

最终我们需要两颗线段树分别维护 Case #1 和 Case #2 ,然后就解决了(这也配 T3 )。