我又来复习\(kmp\)了

其实这道题主要是一个矩阵乘法,但是\(kmp\)在其中也有着非常重要的作用

我们可以这样定义状态\(dp[i][j]\)表示文本串进行到了\(i\)位置,同时文本串在最后和模式串匹配了一共\(j\)位的方案数

于是答案就是\(\sum_{i=0}^{m-1}dp[n][i]\)

之后我们想一下转移

显然\(dp[i]\)需要从\(i-1\)转移过来

但是怎么转移呢

有一个非常直观也非常\(sb\)的想法就是直接\(dp[i][j]=dp[i-1][j-1]\)

毕竟再补上模式串的第\(j\)位就可以啦

但是转移不止这些

那四个画出来的部分是\(next[j]\)

如果我们在转移\(dp[i][j]\)的状态的时候并不让文本串的第\(i\)位和模式串的第\(j\)位相等,而是在这里填上模式串的\(next[j]\)位置上的数

那么很显然\(dp[i-1][nx[j]]+=dp[i-1][j-1]\)

所以我们用\(kmp\)预处理出来一个这样的数组\(a[i][j]\)表示匹配到在模式串上匹配\(j\)向\(i\)转移的时候可以填几个数字

所以现在就有

\[dp[i][j]=\sum_{k=0}^{m-1}dp[i-1][k]*a[i][k]
\]

显然这是一个矩阵乘法就可以优化的柿子

现在的问题就变成了\(a\)数组怎么求

首先求出\(next\)数组,之后枚举这一位填什么,之后往前跳\(nx\),直到匹配就好了

代码

#include<iostream>
#include<cstring>
#include<cstdio>
#define re register
#define maxn 21
int dp[1001][maxn];
char S[maxn];
int n,m,mod;
int nx[maxn];
int ans[maxn][maxn];
int a[maxn][maxn];
inline void did_a()
{
int mid[maxn][maxn];
for(re int i=0;i<m;i++)
for(re int j=0;j<m;j++)
mid[i][j]=a[i][j],a[i][j]=0;
for(re int i=0;i<m;i++)
for(re int j=0;j<m;j++)
for(re int k=0;k<m;k++)
{
a[i][j]+=mid[i][k]*mid[k][j];
if(a[i][j]>=mod) a[i][j]%=mod;
}
}
inline void did_ans()
{
int mid[maxn][maxn];
for(re int i=0;i<m;i++)
for(re int j=0;j<m;j++)
mid[i][j]=ans[i][j],ans[i][j]=0;
for(re int i=0;i<m;i++)
for(re int j=0;j<m;j++)
for(re int k=0;k<m;k++)
{
ans[i][j]+=mid[i][k]*a[k][j];
if(ans[i][j]>=mod) ans[i][j]%=mod;
}
}
inline void quick(int b)
{
while(b)
{
if(b&1) did_ans();
b>>=1;
did_a();
}
}
int main()
{
scanf("%d%d%d",&n,&m,&mod);
scanf("%s",S+1);
nx[0]=nx[1]=0;
for(re int i=2;i<=m;i++)
{
int p=nx[i-1];
while(p&&S[p+1]!=S[i]) p=nx[p];
if(S[p+1]==S[i]) nx[i]=++p;
else nx[i]=0;
}
for(re int i=0;i<m;i++)
for(re char j='0';j<='9';j++)
{
int p=i;
while(p&&S[p+1]!=j) p=nx[p];
if(S[p+1]==j) a[p+1][i]++;
else a[0][i]++;
}
for(re int i=0;i<m;i++) ans[i][i]=1;
quick(n);
int tot=0;
for(re int i=0;i<m;i++)
tot=(tot+ans[i][0])%mod;
std::cout<<tot;
return 0;
}

【[HNOI2008]GT考试】的更多相关文章

  1. 1009: [HNOI2008]GT考试

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数\(X_1X_ ...

  2. 【bzoj1009】[HNOI2008]GT考试

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3018  Solved: 1856[Submit][Statu ...

  3. BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...

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

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

  5. [HNOI2008] GT考试

    [HNOI2008] GT考试 标签 : DP 矩阵乘法 题目链接 题意 n位数中不出现一个子串的方案数. 题解 \(设dp[i][j]\)为前i位匹配到j时的合法方案数.(所谓合法,就是不能有别的匹 ...

  6. BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法

    BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考 ...

  7. BZOJ1009 [HNOI2008]GT考试 矩阵

    去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...

  8. BZOJ 1009 [HNOI2008]GT考试 (KMP + 矩阵快速幂)

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4266  Solved: 2616[Submit][Statu ...

  9. bzoj1009 / P3193 [HNOI2008]GT考试

    P3193 [HNOI2008]GT考试 设$f[i][j]$表示主串匹配到第$i$个位置,不吉利数字匹配到第$j$个位置 $g[i][j]$表示加上某数字使子串原来最多能匹配到第$i$个数字,现在只 ...

  10. bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...

随机推荐

  1. sql = 和<>遵循的sql-92标准的设置SET ANSI_NULLS ON

    说明 SQL-92 标准要求在对空值进行等于 (=) 或不等于 (<>) 比较时取值为 FALSE. 当 SET ANSI_NULLS 为 ON 时,即使 column_name 中包含空 ...

  2. springmvc 框架原理

    先来个原理图,镇博. (图片出处:http://www.cnblogs.com/selene/p/4658554.html,感谢博主的图) 着重看:处理器映射器,处理器适配器,这两个的配置. 这两个的 ...

  3. UI设计师必备

    网站大全 国外的花瓣--Pinterest • The world’s catalog of ideas 字体海洋--求字体网提供中文和英文字体库下载.识别与预览服务,找字体的好帮手原创设计UI--站 ...

  4. csharp:A Custom CheckedListBox with Datasource

    /// <summary> /// (eraghi) /// Custom CheckedListBox with binding facilities (Value property) ...

  5. python中参数传递的方法

    Python中函数传递参数的形式主要有以下五种,分别为位置传递,关键字传递,默认值传递,不定参数传递(包裹传递)和解包裹传递. 1.位置传递实例: def fun(a,b,c) return a+b+ ...

  6. 停课+2week

    可真是,累啊. 本以为停课之后会轻松一点,结果天天好累的说... 今天开始得去锻炼锻炼了... 已经好几次突然一阵晕眩了qwq... 希望我还能挺得住吧,至少要挺到WC结束啊... 这次,可是关系到我 ...

  7. BZOJ4589: Hard Nim(FWT 快速幂)

    题意 题目链接 Sol 神仙题Orzzzz 题目可以转化为从\(\leqslant M\)的质数中选出\(N\)个\(xor\)和为\(0\)的方案数 这样就好做多了 设\(f(x) = [x \te ...

  8. 关于MyEclipse2017Ci10版本的破解和Tomcat9.0的安装搭配使用

    昨天和今天就忙这两件事情了.废话不多说直接上干货! 首先是关于Myeclipse2017的破解,关于这个破解,网上的资源和文件很多,可以自行下载,我就不贴链接了. 我要说的是破解的问题,在这里我们要注 ...

  9. 转:使用VS Code断点调试PHP

    使用VS Code断点调试PHP vs code 使用一款杰出的轻量级代码编辑器,其中的插件工具不胜枚举而且还在不断增加.使用 vs code 调试 PHP 代码更是方便简洁,下面我们来一起看一下. ...

  10. C语言——二叉排序树

    二叉排序树是一种实现动态查找的树表,又称二叉查找树. 二叉排序树的性质: 1. 若它的左子树不为空,则左子树上所有节点的键值均小于它的根节点键值 2. 若它的右子树不为空,则右子树上所有节点的键值均大 ...