题意简述
定义一个字符串 中子序列 的数量为满足 的长度为 ,值域为 的严格单调递增正整数序列 的个数。
定义一个只包含 L、I、F、E 四种字符的字符串是好的,当且仅当这个字符串中只存在恰好一个子序列 IF 与一个子序列 LIE。
请你求出 个字符 L, 个字符 I, 个字符 F, 个字符 E 组成的共 种不同的字符串中好的字符串的数量对 取模的值。
此题多测,设 为组数,对所有数据,满足 ,,。
算法 1
我会爆搜!
时间复杂度:。
期望得分:。
算法 2
我会 DP!
考虑如何判断字符串 中子序列 是否出现了一次。我们可以这样做:
- 维护一个指针 ,初始 。
- 从 到 按顺序枚举 :
- 若 且 ,使 。
- 否则若 ,则必定不满足条件。
- 最后若 则满足,否则不满足。
正确性显然。那么我们直接设 表示目前 L、I、F、E 的数量分别为 ,对于 IF 的指针为 ,对于 LIE 的指针为 时的答案,最后输出 即可。
时间复杂度:。
期望得分:。
算法 3
我会剪枝!
假设 同阶,上面的 DP 只有平方级别的状态是会被转移到的,所以做一下记忆化,只枚举有用的状态就可以通过。具体原因后面会解释。但是由于这个做法常数比较大(需要精细实现才能规避掉哈希表),所以只开了 。可能存在的小常数立方做法可能也可以通过。
时间复杂度:(或 )。
期望得分:。
算法 4
我会观察形态!
- 根据上面的判断方式,只考虑
I、F时字符串应当形如“一段F,IF,一段I”的形式,其中首尾这两段都可以为空。 - 只考虑
L、I、E时字符串应当形如“一段I/E,L,一段E、I、一段L、E、一段L/I”的形式,其中每一个段都可以为空。
将两者结合起来,根据只考虑 L、I、E 时字符串第一段是否存在 I 可以讨论出四种情况:
- 字符串形如“一段
F/E,L,一段F/E、I、一段L、E、一段L、F、一段L/I”的形式,其中每一个段都可以为空。 - 字符串形如“一段
F/E,L,一段F/E、I、一段L、F、一段L、E、一段L/I”的形式,其中每一个段都可以为空。 - 字符串形如“一段
F/E,I,一段E、L、一段E、F、一段E、I、一段L、E、一段L/I”的形式,其中每一个段都可以为空。 - 字符串形如“一段
F/E,I,一段E、F、一段I/E、L、一段E、I、一段L、E、一段L/I”的形式,其中每一个段都可以为空。
发现这四种情况的每个前缀都只有最多两种字母不是“要么几乎没填过,要么几乎全填上了”的状态,所以前面 DP 的有效状态数就是平方级别的。
前两种情况显然是等价的,算出来第一种之后对答案乘以二即可。
对于这两种情况的单个 I 的位置,显然它已经固定了,由于除了右边单个 E 和单个 F,其他的 E 和 F 都在其左边;除了左边的单个 L,其他的 L 和 I 都在其右边,于是这个 I 的位置就是 ,而它左右两边互不干涉。它的左边是 个 F、一个 L、 个 E 任意排列的结果,方案数为 ;它的右边是 个 L、一个 F、一个 E、 个 I 任意排列的结果,并且要求 E 在 F 之前,F 在所有 I 之前,那我们可以将其看作 个 L 与 个 I 任意排列,并将前两个 I 分别替换成 E 和 F,方案数为 ,两边乘起来再乘上 即可。
对于 的特殊性质,后两种情况是不可能出现的,所以只需要分析到这里就可以获得对应分数。
对于第三种情况的分析也是类似的,方案数为 。
最后一种情况比较特殊,它没有前三种情况这么好的性质,所以我们直接枚举中间那个 I/E 段中 I 的个数 (),即可确定后面那个单个 I 的位置为 ,它左右两边互不干涉。它的左边是 个 E 与剩下的东西归并起来的结果,方案数为 ;它的右边是 个 L 与剩下的东西归并起来的结果,方案数为 。
那么我们就算完了所有情况的答案,瓶颈在最后一种情况的枚举。
时间复杂度:。
期望得分:。