1 条题解
-
0
思路
把所有模式串插入 AC 自动机。自动机的每个结点记录:当前读入串的最长后缀对应哪个前缀状态,以及到达该状态时已经匹配到哪些模式串。失配指针指向的结点所匹配到的模式也必须计入当前结点。
随后按生成字符串的长度做动态规划。状态由自动机结点和已经出现过的模式集合组成,加入一个字符后沿自动机转移,并把新结点的匹配集合并入状态。
做法
建立 Trie,并用广度优先搜索求失配指针和所有字符转移。设
mask[u]表示到达结点 时,以当前位置结尾的模式集合;构建失配指针时,将失配结点的集合并入它。令 表示已经生成 个字符、自动机位于结点 、已经出现的模式集合为 的方案数。枚举下一个小写字母,转移到结点 ,并把集合更新为 。初始状态为空串、根结点、空集合。生成恰好 个字符后,把集合包含全部模式的状态求和。
当 时,同样的思想退化为单模式 KMP 自动机,只需区分是否已经出现该模式。所有模式长度均为 时,这些模式对应互不相同的必需字母,可以直接对缺失字母集合做容斥。
正确性证明
AC 自动机状态始终等于当前生成前缀的最长后缀中、同时也是某个模式前缀的字符串。通过失配指针传播后的匹配集合,恰好包含所有在当前位置结束的模式。因此每次转移把该集合并入历史集合后,动态规划记录的集合恰好是当前前缀中已经作为子串出现过的全部模式。
初始状态对应唯一空串。每个长度为 的字符串都能唯一分解为一个长度为 的前缀和最后一个字母,所以转移既不会遗漏,也不会重复计数。归纳可知, 精确统计所有满足状态描述的长度为 的字符串。最终集合为全集,当且仅当全部模式都出现过,因此求和结果就是题目答案。
复杂度
自动机结点数记为 ,有 。时间复杂度为 ,空间复杂度为 。
- 1
信息
- ID
- 979
- 时间
- 3000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 1
- 已通过
- 1
- 上传者