题目链接: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】的更多相关文章

  1. BZOJ 1009 GT考试 (AC自动机 + 矩阵乘法加速dp)

    题目链接: https://www.lydsy.com/JudgeOnline/problem.php?id=1009 题意: 准考证号为\(n\)位数\(X_1X_2....X_n(0<=X_ ...

  2. BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法

    标题效果:给定的长度m数字字符串s.求不包括子s长度n数字串的数目 n<=10^9 看这个O(n)它与 我们不认为这 令f[i][j]长度i号码的最后的字符串j位和s前者j数字匹配方案 例如,当 ...

  3. P3193 [HNOI2008]GT考试(KMP+矩阵乘法加速dp)

    P3193 [HNOI2008]GT考试 思路: 设\(dp(i,j)\)为\(N\)位数从高到低第\(i\)位时,不吉利数字在第\(j\)位时的情况总数,那么转移方程就为: \[dp(i,j)=dp ...

  4. bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂

    https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9 ...

  5. bzoj 1009 [HNOI2008]GT考试(DP+KMP+矩阵乘法)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1009 [题意] 给定一个字符串T,问长度为n且不包含串T的字符串有多少种. [思路] ...

  6. 【bzoj1444】[Jsoi2009]有趣的游戏 AC自动机+矩阵乘法

    题目描述 输入 注意 是0<=P 输出 样例输入 样例输出 题解 AC自动机+矩阵乘法 先将所有字符串放到AC自动机中,求出Trie图. 然后构建邻接矩阵:如果x不是某个字符串的末位置,则x连向 ...

  7. 形态形成场(矩阵乘法优化dp)

    形态形成场(矩阵乘法优化dp) 短信中将会涉及前\(k\)种大写字母,每个大写字母都有一个对应的替换式\(Si\),替换式中只会出现大写字母和数字,比如\(A→BB,B→CC0,C→123\),代表 ...

  8. 斐波那契数列 矩阵乘法优化DP

    斐波那契数列 矩阵乘法优化DP 求\(f(n) \%1000000007​\),\(n\le 10^{18}​\) 矩阵乘法:\(i\times k\)的矩阵\(A\)乘\(k\times j\)的矩 ...

  9. BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )

    写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...

随机推荐

  1. BeagleBone Black Linux驱动程序开发入门(0): 开发环境

    搭建arm-linux交叉编译环境的教程有很多,这里只作简要说明.Host宿主机是Ubuntu10.04,我把它装在Windows XP的VirtualBox虚拟机中,这样相当于一台主机有两个操作系统 ...

  2. 插件化技术在安卓sdk开发中实际应用

    笔者从 2016 年初就因为公司业务需求转战 android sdk 开发, 应用插件化技术将公司 android sdk 重新翻版.先来说说需求. 由于笔者所在一家创业公司, android sdk ...

  3. RPM vs SRPM

    RPM 全名是『 RedHat Package Manager 』简称则为 RPM 啦!顾名思义,当初这个软件管理的机制是由 Red Hat 这家公司发展出来的. RPM 是以一种数据库记录的方式来将 ...

  4. Python 学习开发笔记之IO操作

    文件或者目录的路径操作 获取当前工作目录 import os import sys cwd = os.getcwd() 路径的拼接 os.path.join(path,"dir") ...

  5. 深入理解计算机系统第二版习题解答CSAPP 2.3

    填写空白.单字节可以用两个十六进制数表示. 十进制 二进制 十六进制 0 0000 0000 0x00 167 1010 0111 0xA7 62 0011 1110 0x3E 188 1011 11 ...

  6. ThinkPHP函数详解系列

    为了能方便大家学习和掌握,在这里汇总下ThinkPHP中的经典函数用法 A 函数:实例化控制器R 函数:直接调用控制器的操作方法C 函数:设置和获取配置参数L 函数:设置和获取语言变量D 函数:实例化 ...

  7. js数组&&字符串&&定时器1

    一.简单计算命令eval var str="6*5"; alert(eval(str)); 注意:不安全,一般都不会去用   二.id&&name id:只能唯一 ...

  8. 第二篇:gradle脚本运行环境分析(gradle的语义模型)

    引言:通过上一篇的论述,我们知道gradle脚本是如假包换的groovy代码,但是这个groovy代码是运行在他的上下文环境里面的,学名叫语义模型.这一篇我们就来看看他的语义模型到底是什么,如何使用. ...

  9. MVC小系列(十四)【MVC+ZTree大数据异步树加载】

    ZTree是一个jquery的树插件可以异步加载 第一步定义一个标准的接口(指的是与ztree默认的数据元素保持一致) /// <summary> /// ZTree数据结构 /// &l ...

  10. SQL Server 阻止了对组件 'xp_cmdshell' 的 过程'sys.xp_cmdshell' 的访问

    sql server 2005: EXEC sp_configure N'show advanced options', N'1' RECONFIGURE WITH OVERRIDEEXEC sp_c ...