CF1798E

题面

看到要求每一位的答案,首先考虑倒着扫,因为加数一般都比删数好做。

对于任意长为 \(m\) 的的序列 \(\{b\}\),我们都可以通过将 \(b_1\) 改成 \(1\),将 \(b_2\) 改成 \(m-2\) 使得 \(\{b\}\) 成为一个 multitest,因此操作数不会超过 \(2\)

现在讨论答案的三种情况:

  • 答案为 \(0\)\(\{b\}\) 已经是一个 multitest 了。
  • 答案为 \(1\)\(\{b\}\) 可以通过一次修改变成一个 multitest。
  • 答案为 \(2\):排除了前两种之后的情况。

对于一个位置 \(i\),它的后缀能构成一个 multitest 的充要条件是:\(i+1\) 的后缀能构成若干个 test,且 \(a_i\) 的值等于 \(i+1\) 的后缀构成的 test 数。

\(f_i\) 表示 \(i\) 的后缀能构成的 test 的个数,不难得出转移方程如下:

\[f_i=\begin{cases} 1,\qquad i+a_i=n\\ 0,\qquad i+a_i>n\>\operatorname{or}\>f_{i+a_i+1}=0\\ f_{i+a_i+1}+1,\qquad \text{otherwise} \end{cases}\]

\(\{f\}\) 可以 \(\Theta(n)\) 求出。第 \(i\) 位答案为 \(0\) 的充要条件就是 \(f_{i+1}\neq 0\)\(a_i=f_{i+1}\)

如果答案不为 \(0\),考虑两种情况:

  1. \(f_{i+1}\neq 0\),但是 \(a_i\neq f_{i+1}\)
  2. \(f_{i+1}=0\)

对于第一种情况,令 \(a_i\leftarrow f_{i+1}\) 即可,操作数为 \(1\)

对于第二种情况,如果想要答案为 \(1\),显然需要对 \(i+1\) 的后缀中的某一个数进行修改,使修改后 \(i+1\) 的后缀能构成 \(a_i\) 个 test。

\(g_i\) 表示在 \(i\) 的后缀中进行一次修改后,能得到的最多 test 数。

这个修改有两种情况:

  1. 修改 \(a_i\)。这意味着我们可以随意改变第一个 test 的长度,也就是这第一个 test 可以接在后面的任意一个状态的前面,这种情况能得到的最大值为 \(\max\limits_{j=i+1}^nf_j+1\)
  2. 不修改 \(a_i\)。因为 \(a_{i+1}\)\(a_{i+a_i}\) 之间的数会被 \(a_i\) 所在的 test 所包含,所以只有修改 \(i+a_i+1\) 的后缀中的某个数才能有贡献。因此这种情况能得到的最大值为 \(\max\limits_{j=i+a_i+1}^ng_j+1\)

后缀最大值可以边做边求,因此 \(\{g\}\) 也可以 \(\Theta(n)\) 求出。那么“对 \(i+1\) 的后缀中的某一个数进行修改后,\(i+1\) 的后缀能构成 \(a_i\) 个 test”的充要条件就是 \(g_{i+1}\ge a_i\)

之所以这里是大于等于号,是因为如果能修改 \(a_p\) 形成 \(x\) 个 test,那一定可以通过“让 \(a_p\) 更大,覆盖掉下一个 test”或“让上一个 test 的第一个元素更大,覆盖掉 \(a_p\) 所在的 test”,形成 \(x-1\) 个 test。

剩下的情况答案就是 \(2\) 了。

时间复杂度显然 \(\Theta(n)\)

赛时 AC 记录

posted @ 2023-04-24 19:32  untitled0  阅读(33)  评论(0)    收藏  举报