[BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】
题目链接:BZOJ - 1009
题目分析
题目要求求出不包含给定字符串的长度为 n 的字符串的数量。
既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j 位的字符串个数,然后转移就是可以从第 j 位加上一个字符转移到另一个位置。
然而..我并没有写过KMP + DP,我觉得还是写AC自动机+DP比较简单..于是,尽管只有一个模式串,我还是写了AC自动机+DP。
然后就是建出AC自动机,f[i][j] 表示长度为 i ,走到节点 j 的字符串的个数。然后 f[i][] 是由 f[i - 1][] 转移过来的。
这个 DP 的转移满足 f[i][j] = sigma(f[i - 1][k] * A[k][j]) ,所以可以用矩阵乘法优化。
代码
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime> using namespace std; const int MaxL = 20 + 5; int n, m, Mod, Ans, Root, Zero;
int Child[MaxL][11], Fail[MaxL]; char S[MaxL]; struct Matrix
{
int Num[MaxL][MaxL];
} M; Matrix operator * (Matrix A, Matrix B)
{
Matrix ret;
memset(ret.Num, 0, sizeof(ret.Num));
for (int i = 0; i < m; ++i)
for (int j = 0; j < m; ++j)
{
if (A.Num[i][j] == 0) continue;
for (int k = 0; k < m; ++k)
{
ret.Num[i][k] += A.Num[i][j] * B.Num[j][k];
ret.Num[i][k] %= Mod;
}
}
return ret;
} Matrix Pow(Matrix a, int b)
{
Matrix ret, f;
memset(ret.Num, 0, sizeof(ret.Num));
for (int i = 0; i < m; ++i) ret.Num[i][i] = 1;
f = a;
while (b)
{
if (b & 1) ret = ret * f;
b >>= 1;
f = f * f;
}
return ret;
} void Prepare()
{
Root = 0;
for (int i = 0; i < m; ++i)
Child[i][S[i + 1] - '0'] = i + 1;
Zero = m + 1;
Fail[Root] = Zero;
for (int i = 0; i <= 9; ++i)
Child[Zero][i] = Root;
for (int i = 0; i < m; ++i)
for (int j = 0; j <= 9; ++j)
if (S[i + 1] - '0' == j) Fail[Child[i][j]] = Child[Fail[i]][j];
else Child[i][j] = Child[Fail[i]][j];
for (int i = 0; i < m; ++i)
for (int j = 0; j <= 9; ++j)
if (Child[i][j] != m)
++M.Num[i][Child[i][j]];
} int main()
{
scanf("%d%d%d", &n, &m, &Mod);
scanf("%s", S + 1);
Prepare();
M = Pow(M, n);
Ans = 0;
for (int i = 0; i < m; ++i)
Ans = (Ans + M.Num[0][i]) % Mod;
printf("%d\n", Ans);
return 0;
}
[BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】的更多相关文章
- BZOJ 1009 GT考试 (AC自动机 + 矩阵乘法加速dp)
题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1009 题意: 准考证号为\(n\)位数\(X_1X_2....X_n(0<=X_ ...
- BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法
标题效果:给定的长度m数字字符串s.求不包括子s长度n数字串的数目 n<=10^9 看这个O(n)它与 我们不认为这 令f[i][j]长度i号码的最后的字符串j位和s前者j数字匹配方案 例如,当 ...
- P3193 [HNOI2008]GT考试(KMP+矩阵乘法加速dp)
P3193 [HNOI2008]GT考试 思路: 设\(dp(i,j)\)为\(N\)位数从高到低第\(i\)位时,不吉利数字在第\(j\)位时的情况总数,那么转移方程就为: \[dp(i,j)=dp ...
- bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂
https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9 ...
- bzoj 1009 [HNOI2008]GT考试(DP+KMP+矩阵乘法)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1009 [题意] 给定一个字符串T,问长度为n且不包含串T的字符串有多少种. [思路] ...
- 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法
题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...
- 形态形成场(矩阵乘法优化dp)
形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...
- 斐波那契数列 矩阵乘法优化DP
斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007\),\(n\le 10^{18}\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...
- BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )
写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...
随机推荐
- Linux--------------安装mysql(2)
在 CentOS7 上安装 MySQL5.7 1 通过 SecureCRT 连接到阿里云 CentOS7 服务器: 2 进入到目录 /usr/local/ 中:cd /usr/local/ 3 创建目 ...
- 调用iframe 中的js[兼容各种浏览器]
*chrome浏览器需要在服务器环境中测试 <!DOCTYPE html> <html> <head> <meta http-equiv="cont ...
- Unity3D 之NGUI各种脚本及应用
这里来介绍一下NGUI的各种脚本的作用,以便以后需要某种效果的时候,去添加相应的脚本去实现效果 UIButton --> 按钮脚本 UIPanel --> 面板脚本 UIToggle ...
- java Spring配置数据单元
基本原理 - 容器和bean 在Spring中,那些组成你应用程序的主体(backbone)及由Spring IoC容器所管理的对象,被称之为bean. 简单地讲,bean就是由Spring容器初始化 ...
- 关于sqlserver 2008 远程导入表数据
/*不同服务器数据库之间的数据操作*/ --创建链接服务器 exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 ' ex ...
- 关于MySQL中使用LOAD DATA INFILE导入csv文件时的日期格式问题
在使用MySQL时,常常会用到Load Data Infile来导入数据,在遇到Date类型的列时,有时会遇到格式转换的问题: 首先创建一张简单的people表,包含名字,生日,年龄三个字段: mys ...
- Web开发必备资源汇总[转]
导读:原文来自< Best “must know” open sources to build the new Web>,译文由酷壳网陈皓整理编译< 开源中最好的Web开发的资源 & ...
- java之sleep、wait、yield、join、notify乱解
① 这两个方法来自不同的类分别是,sleep来自Thread类,和wait来自Object类. sleep是Thread的静态类方法,谁调用的谁去睡觉,即使在a线程里调用b的sleep方法,实际上还是 ...
- (转)Libevent(3)— 基础库
转自:http://name5566.com/4202.html 参考文献列表:http://www.wangafu.net/~nickm/libevent-book/ 此文编写的时候,使用到的 Li ...
- 使用CPA4破解经典密码算法
下面是一段经过经典密码算法加密的密文(加密算法未知): yvvnerujjvnywhbdvkpchfgvjtzwqsuporqfzpoekkjgziicdwwkeejdsruef whwseyej ...