CF1858D Trees and Segments

发布时间 2023-09-15 17:13:06作者: FOX_konata

原题

翻译

这题预期说是\(dp\),不如说是预处理吧233

首先我们同时考虑两维限制是很困难的,如果我们想直接\(dp\)要设很多状态,复杂度爆炸

因此我们考虑暴力枚举一维。具体的,我们枚举把\([l,r]\)内的所有数染成\(0\),我们可以通过前缀和得到操作次数\(t\)(即为区间内\(1\)的个数),然后我们只需要考虑从\([1,l)\)\((r,n]\)中选一段区间,用\(\leq K - t\)次操作把他染成全\(1\),使得区间长度最大。

于是我们设\(pre_{i,j}\)表示\(i\)作为右端点,可以使用\(j\)次操作,能染成全\(1\)的最大长度。同理,设\(suf_{i,j}\)表示\(i\)作为区间左端点,用\(j\)次全\(1\)的最大长度。可以发现左端点单增,因此我们可以尺取\(O(n^2)\)解决问题

在预处理出\(pre,suf\)数组后,我们对他做一个前缀后缀最大值即可:

\[\begin{align} pre_{i,j} = \max{(pre_{i-1,j}, r - l + 1)} \\ suf_{i,j} = \max{(suf_{i+1,j}, r - l + 1)} \\ \end{align} \]

有些人就会有疑问:外面不还要再枚举\(a\)的值吗,这样做不就成了\(O(n^3)\)的了吗

但我们发现,我们每次只需要知道最长\(0\)\(=i\)时的最大\(\max{(pre_{l-1}{t-K}, suf_{r+1}{t-K})}\),因此我们可以先用一个数组\(ans_i\)表示最长\(0\)段长为\(i\)时最长\(1\)段长度。处理完\(ans\)后再在外面枚举\(a\)的值,答案即为\(\max_{i=0}^{n}{i \times a + ans_i}\)

最终复杂度$O(n^2)