【[HNOI2008]GT考试】
我又来复习\(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\)转移的时候可以填几个数字
所以现在就有
\]
显然这是一个矩阵乘法就可以优化的柿子
现在的问题就变成了\(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考试】的更多相关文章
- 1009: [HNOI2008]GT考试
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数\(X_1X_ ...
- 【bzoj1009】[HNOI2008]GT考试
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3018 Solved: 1856[Submit][Statu ...
- BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...
- BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )
写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...
- [HNOI2008] GT考试
[HNOI2008] GT考试 标签 : DP 矩阵乘法 题目链接 题意 n位数中不出现一个子串的方案数. 题解 \(设dp[i][j]\)为前i位匹配到j时的合法方案数.(所谓合法,就是不能有别的匹 ...
- BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法
BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考 ...
- BZOJ1009 [HNOI2008]GT考试 矩阵
去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...
- BZOJ 1009 [HNOI2008]GT考试 (KMP + 矩阵快速幂)
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4266 Solved: 2616[Submit][Statu ...
- bzoj1009 / P3193 [HNOI2008]GT考试
P3193 [HNOI2008]GT考试 设$f[i][j]$表示主串匹配到第$i$个位置,不吉利数字匹配到第$j$个位置 $g[i][j]$表示加上某数字使子串原来最多能匹配到第$i$个数字,现在只 ...
- bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...
随机推荐
- 用jquery把一个List里面的对象的属性,依次填入到一个table里面啊
假设list格式如下list = [{"id":"1","name":"A","age":20}, ...
- .net core 导出excel
1.使用NuGet 安装 EPPlus.Core, 2.代码如下 using OfficeOpenXml; using OfficeOpenXml.Style; public IActionResul ...
- [LeetCode]Generate Parentheses题解
Generate Parentheses: Given n pairs of parentheses, write a function to generate all combinations of ...
- K:双栈法求算术表达式的值
相关介绍: 该算法用于求得一个字符串形式的表达式的结果.例如,计算1+1+(3-1)*3-(21-20)/2所得的表达式的值,该算法利用了两个栈来计算表达式的值,为此,称为双栈法,其实现简单且易于理 ...
- MySQL的预编译功能
1.预编译的好处 大家平时都使用过JDBC中的PreparedStatement接口,它有预编译功能.什么是预编译功能呢?它有什么好处呢? 当客户发送一条SQL语句给服务器后,服务器总是需要校验S ...
- Linux菜鸟简单命令
想要使用Linux,以下这些命令不可少的哦! 我在工作中经常用到的大多数都是一些文件的查找,和上传下载什么的,没什么技术含量,所以除了自己整理的之外,还有借鉴的别的大神的一些命令,我会在最后标注的\( ...
- 利用PIE实现全球云分布图的效果
1.问题背景: 最近项目中获得了一份全球云分布图,客户要求把云显示在全球地图上,出现云的效果,如下图所示: [全球云分布图] [世界地图云示意图] 2.解决思路 咨询专业的业务人员,建议我测试下试试地 ...
- Android SDK开发与使用的那些事儿
前言 最近由于工作需要,将应用里的部分功能独立了出来,封装成 SDK 提供给合作伙伴使用.由于经验不足,网上也没多少写这方面内容的文章,遇到了不少的坑,决定记录下来. SDK 其实,刚说到要写SDK也 ...
- Python爬虫教程-05-python爬虫实现百度翻译
使用python爬虫实现百度翻译功能 python爬虫实现百度翻译: python解释器[模拟浏览器],发送[post请求],传入待[翻译的内容]作为参数,获取[百度翻译的结果] 通过开发者工具,获取 ...
- python item repr doc format slots doc module class 析构 call 描述符
1.item # __getitem__ __setitem__ __delitem__ obj['属性']操作触发 class Foo: def __getitem__(self, item): r ...