划分子段相关问题
子段和相关问题
线性序列最大子段和
法一
考虑 dp。\(f_i\) 表示以 \(i\) 结尾的最大子段和,有 \(f_i = \max(0, f_{i-1} + A_i)\)
法二
考虑预处理前缀和 \(s_i\)。枚举 \(i\) 作为右端点,只需找 \(s_i - s_{j-1}\) 最大,即 \(s_{j-1}\) 的最小值。动态维护 \(j\) 即可。
子段长度 \(\le m\) 的最大子段和
预处理前缀和 \(s_i\)。对于每个 \(i\) 找到 \(j\) 使得 \(j \in [i-m,i-1]\) 且 \(s_i - s_{j-1}\) 最大。单调队列或 ds 维护即可。
子段长度 \(\ge m\) 的最大子段和
法一
单调队列或 ds 的做法是同理的。
法二
很有意思的做法。考虑拼接的思想。
预处理 \(f_i\) 表示以 \(i\) 结尾的前缀最大子段和,\(g_i\) 表示后缀。枚举一个长度为 \(m\) 的子段 \([i,j]\),记其和为 \(s\)。该子段的贡献就是 \(s + f_{i-1} + g_{j+1}\)。
环状最大子段和
法一
倍长序列,做一遍长度 \(\le n\) 的最大子段和即可。
法二
我们思考最大子段和的两种情况。
- 子段没有跨过 \(A_n\) 与 \(A_1\) 的端点。此时当线性做是对的。
- 子段跨过了 \(A_n\) 与 \(A_1\) 的端点。此时你发现剩下没选的部分就是最小子段和,当线性做也是对的。注意最小子段和不能选完,枚举扔掉哪个即可。
是线性的。
最大双子段和
仍然是拼接的思想。不再赘述。
环形最大双子段和
法一
考虑照搬最大双子段和的做法。枚举断点,然后对于每一个线性序列都做一遍。容易证明这样会覆盖到所有满足要求的答案。\(\mathcal{O(n^2)}\)。
法二
考虑环最大子段和的思考方式。对于一个双子段,同样分为两种情况:
- 没有一个跨越端点。这样直接线性做就是对的。
- 其中一个跨过了端点。同理发现补集是最小双子段和。那么线性做一遍最小双子段和即可。注意两个最小双子段可以取空。以及需要把 \(1,n\) 给扣掉,防止最小双子段选上。
线性。
最大 \(m\) 段子段和
区间 dp。待补。
环形最大 \(m\) 段子段和
wqs 二分。待补。
只含正整数的序列中满足区间和 \(\ge S\) 的最小子段和的长度
双指针板子。
浙公网安备 33010602011771号