AGC027E ABBreviate
题面
简化题意
给定一个 ab 串,每次可以选择两个相邻的 a 换成一个 b;或者把相邻两个 b 换成 a,求可以构造出多少个不同的字符串。
。
题解
显然,形如 这样的字符串是无法进行任何操作的,答案为 。进一步地,对于一对连续的 a 或者 b 都可以进行操作。因此一个无法操作的序列一定是 ab 交替的。且任何可以操作的序列一定可以转化为一个不可操作的序列。
对于一个可操作序列,考虑求出其是否能转化为一个不可操作序列 。
因为 不可操作, 可操作,不妨认为 的若干不重叠的子串,分别操作后得到了 的一个字符。
随意提取 的一个子串,只要其可操作,就一定能被缩成一个字符。
证明
对于不可操作且长度大于 的字符串,一定不能被缩。而对于一个可操作的字符串,操作一次后长度会减小 。若此时仍可以继续操作则继续。
若可操作的字符串操作一次后长度没有变成 且不可操作,说明本处操作后变成的字符和两边都不同。即 操作中间两个 a,然而可以先操作左右两侧的 a,就可以消除这种情况。
下面考虑如何确定一个子串会被缩成什么字符:将 a 看作 ,b 看作 2,则每次操作相当于把两个连续且相同的数加起来模 。
维护模三意义下的前缀和就可以快速算出一个子串会变成什麼字符。注意到如果子串的权值为 ,说明 ab 数量相等,此时要么这个子串不可操作,要么可以划分为权值不同的两个子串。
进一步解决如何判断把 变成 合法。不妨假设 是任意字符串。
记 为 的子串 模三意义下的数字和, 同理。设 。显然第一个需要满足 。然后考虑从左到右给 分段,使得 的第 段对应 。
不妨做一个贪心,每次分段的长度尽量小,例如 :
- ,分段:。
- ,分段:。
- ,分段:。
考虑 的剩余部分是一个不可操作序列,有 ,因此显然 ,把最后两端合成一段即可。
将 按照最短原则分段,如果最后有剩余,则剩余部分的权值和一定是 。
证明
设 被分成 段,且最后一段的权值不为 。
由于分段按最短原则,无法拆分一个段为两个,而合并两个段是不合法的(段数与 不匹配)。因此只能合并最后一段和倒数第二段,由于最后一段权值和不为 ,但是倒数第二段已经和 匹配了,合并就会导致权值部匹配。因此这种情况一定不合法。
得到上述结论后就可以 DP 了。设 表示考虑到 ,能匹配到多少个 。
的对应段可以是 或 ,根据最短原则,预处理每个 下一个最近的位置 满足 。
转移时快速找到以 为上一段的末尾,下一段的区间是什么即可。设 为开头时,一段的结尾为 :
初始状态 。
按照这种方法 DP,得到的 为分段后恰好和 匹配的数量,还要加上可能多出来一段的情况。需要判断如果 ,则最后答案还要加上 的值。特判 。
代码
1 | if(a[n]==1){ |
- 标题: AGC027E ABBreviate
- 作者: Arahc
- 创建于 : 2022-01-02 08:00:00
- 更新于 : 2023-03-17 15:13:26
- 链接: https://arahc.github.io/2022/01/02/【题解】AGC027E-ABBreviate/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。