ARC089D 题解

First Post:

Last Update:

感觉这题顺推下来并不难,关键是对过程中的一些 case 如何统一起来,从而减少讨论工作量。 结论比较有意思,但整道题过程较繁琐。也是一道好题。

先考虑对于结果序列 ,我们能不能将其染成。

首先对于 中为白色的部分,其两边是独立的子问题。可以分开。

先考虑 没有白色的情况,因为操作都是区间覆盖,所以 中的相等连续段可以缩在一起。此时 一定是 RB 交错的形式。注意到如果首尾为 B,在首尾添加一个 R 没有影响(只需要让第一次 R 操作"扩大"一下即可)。所以,每一种只有红蓝色的结果序列,都能被化归到 的形式。

那最后的 也可以看作若干段 与中间一些 拼成的串。设共有 段,每段长度为 。(下文的“长度” 都定义为其中 的个数)

我们考虑一个长度为 的段需要什么样的操作将其染成。

时,只需一个操作 。 时,需要两个操作 。 时,操作序列 与 都是可行的。

用数学归纳法可以得到,当 时,只要操作序列前两个是 ,后面接 个任意字符就行。显然这也是充要条件。

此时我们发现 与 要分开考虑,枚举 表示 的个数。那我们需要将 串分为 个 与 个满足那些段的操作序列。

那么在原串中找到最前面的 个 。在最前面的 个 后面分别找到最前的一个 与其配对。将这些字符标记为已经使用。显然我们找到的这些作为那 个操作序列的开头一定是不劣的。

设 表示第 对 后面的空余字符数。我们将 与 从小到大排序,对 的限制就是 。

考虑 DP 排序后的 数组,设 表示当前到第 位,当前 ,。转移枚举下一个 相等段的长度 与值 :。(乘组合数是因为我们 DP 的是排序后的 数组,要乘组合数还原成排序前的)。

容易用前缀和优化做到 。

但我们还要解决一个问题,现在我们考虑的 都对应的是原序列的一段 ,怎么将我们考虑的东西还原到原序列上。

先考虑单个 的部分,它恰好有 段,但是首尾两段可能为空,那么我们在这个部分的两端加入两个虚拟的 ,此时这两段不可能为空,但序列长度变成 。这一个段与两边的两个 一共会形成 个分界点,但又是首尾有例外,所以我们在原序列首尾各加一个 ,此时序列长度为 ,一共有 个分界点,那么将缩段后的序列对应到原序列的方案数就是 。

综上所述,我们枚举 ,表示总的 RB 段数以及单个 R 的段数,然后找到最前的 个 与对应最前的 个 ,接着跑那个 DP,最后枚举 的值统计答案。总时间复杂度上界为 ,但显然跑不满,很轻松地过了 。