[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) ...
随机推荐
- java pdu短信解码
java pdu短信解码 长短信未验证 有兴趣的可以试试 根据python的方法改写的 /** * PDU短信解析 * * * @param pduPayload * @return */ publi ...
- 配置servers时,错误:Setting property 'source' to 'org.eclipse.jst.jee.server:hczm' did not find a matching property
WARNING: [SetPropertiesRule]{Server/Service/Engine/Host/Context} Setting property 'source' to 'org.e ...
- php笔记07:http响应详解(禁用缓存设置和文件下载)
演示如何通过Http响应控制页面缓存,在默认情况下,浏览器是会缓存页面的1.禁用缓存设置 (1).我在...\htdocs\http文件夹,写一个cache.php文件如下: <?php ech ...
- 集合练习——Set部分
我们知道list存储的是有序不唯一的元素. set存储的是无序唯一的元素. 那么下面看一个例子吧: package CollectionPart; import java.util.HashSet; ...
- 查看kindle paperwhite2上卡索引书籍的方法
昨天kindle耗电量突然加快,经过检查和网络搜索得知是卡索引导致的耗电量增大.我自己通过关闭索引的方式解决了这个问题. 在这个过程中发现了一个可以直接找到所有卡索引书籍的方法,在此分享一下. 首先打 ...
- Fetch的使用
import React,{ Component } from 'react'; import { AppRegistry, ListView, Image, Text, StyleSheet, Vi ...
- VS2010数据库连接问题
我用SQL server 2008写了一个小表格,运行VS的前选择了 工具-连接数据库,然后选择了那个表格的名称.运行后出现如下错误提示,请问是哪里出了问题呢? 数据库连接版本有问题.在VS中把信用数 ...
- MyEclipse2014中项目名更改后如何使用新的项目名部署到Tomcat中去
在项目中调试的时候突然发现我复制的项目(项目名修改过了)部署在Tomcat中运行的时候还是显示的是原来的项目名,以至于我使用新的项目名称作为URL请求竟然是404,我去,当时感觉就不怎么好了. 当然, ...
- Ext.Net学习笔记12:Ext.Net GridPanel Filter用法
Ext.Net学习笔记12:Ext.Net GridPanel Filter用法 Ext.Net GridPanel的用法在上一篇中已经介绍过,这篇笔记讲介绍Filter的用法. Filter是用来过 ...
- Java中多线程的使用!!
简介: 1.要了解多线程,首先我们得先了解进程和线程.那么什么是进程?进程就是一个正在运行的程序分配内存让应用程序能够运行的叫做进程.那么什么又是线程呢?线程:在一个程序中,负责代码的执行 ...