不包含任何模式串的字符串个数
题目描述
生成一个长度为 \(n\),字符集为 \(\Sigma\) 的字符串 \(S\) .
给定若干模式串 \(s_{1\dots m}\),要求 \(S\) 中不能有任何一个子串为模式串 .
问字符串 \(S\) 的个数 .
答案对 \(P\) 取模,\(P\) 不超过 \(2^{31}\) .
数据范围:
- Task 1. \(n\le 60\),\(m\le 100\),\(|s|\le 100\)(JSOI2007 文本生成器) .
- Task 2. \(n\le 10^9\),\(m\le 20\),\(\sum|s|\le 20\)(HNOI2008 GT考试 加强版) .
\(|\Sigma|\le 10\) .
咋做
首先建出模式串的 AC 自动机(不妨记转移函数为 \(trans\)) .
考虑 DP,令 \(dp_{i,j}\) 表示串长为 \(i\),在 AC 自动机上走到编号为 \(j\) 的节点的合法串个数 .
则在 AC 自动机上走一步即可完成转移:
\[\large dp_{i+1, trans(j, c)} = \sum dp_{i,j}\qquad (c\in\Sigma)
\]
暴力 DP,时间复杂度 \(O(|\Sigma|n\sum|s|)\) .
大概这么写:
dp[0][0] = 1;
for (int i=0; i<n; i++)
for (int j=0; j<=cc; j++)
for (int k=0; k<Sig; k++)
if (!mark[tr[j][k]]) dp[i+1][tr[j][k]] = (dp[i+1][tr[j][k]] + dp[i][j]) % P;
Task 1 完美解决 .
然而我们发现 \(i\) 这个玩意和内层转移几乎没关系,只是为了保证转移顺序 .
也就是说这玩意相当于进行了 \(i\) 次内层转移,\(i\) 一维枚举根本没用 .
所以我们构建出内层转移矩阵,然后快速幂即可 .
设 AC 自动机大小为 \(c\),则 DP 部分时间复杂度为 \(O(c^3\log n)\) .
Task 2 完美解决 .
以下是博客签名,正文无关
本文来自博客园,作者:yspm,转载请注明原文链接:https://www.cnblogs.com/CDOI-24374/p/16020972.html
版权声明:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议(CC BY-NC-SA 4.0)进行许可。看完如果觉得有用请点个赞吧 QwQ

浙公网安备 33010602011771号