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\}\) 可以 \(\Theta(n)\) 求出。第 \(i\) 位答案为 \(0\) 的充要条件就是 \(f_{i+1}\neq 0\) 且 \(a_i=f_{i+1}\)。
如果答案不为 \(0\),考虑两种情况:
- \(f_{i+1}\neq 0\),但是 \(a_i\neq f_{i+1}\)。
- \(f_{i+1}=0\)。
对于第一种情况,令 \(a_i\leftarrow f_{i+1}\) 即可,操作数为 \(1\)。
对于第二种情况,如果想要答案为 \(1\),显然需要对 \(i+1\) 的后缀中的某一个数进行修改,使修改后 \(i+1\) 的后缀能构成 \(a_i\) 个 test。
设 \(g_i\) 表示在 \(i\) 的后缀中进行一次修改后,能得到的最多 test 数。
这个修改有两种情况:
- 修改 \(a_i\)。这意味着我们可以随意改变第一个 test 的长度,也就是这第一个 test 可以接在后面的任意一个状态的前面,这种情况能得到的最大值为 \(\max\limits_{j=i+1}^nf_j+1\)。
- 不修改 \(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)\)。

浙公网安备 33010602011771号