DP/KMP/矩阵乘法


  好神的题啊……跪了跪了

  $n\leq 10^9$是什么鬼……我们还是先不要考虑这个鬼畜的玩意了>_>

  用类似数位DP的思路,我们可以想到一个DP方程:$f[i][j]$表示前 i 位数字,它的最后 j 位与不吉利串匹配的方案数,显然有$ans=\sum_{i=0}^x f[n][i]$

  然后就是转移的问题了= =那么依旧按照数位DP的想法(其实是硬扯到那的吧……怎么理解都可以,重点是明白转移方程)可以想到:从 i 转移到 i+1,有10种方案,其中一种会使得匹配长度+1,即$f[i+1][j+1]+=f[i][j]$那么其他的方案呢?并不都会使得匹配长度归0,想到这你大概已经想到了,对!就是KMP!字符串匹配时的fail指针!那么转移的方式就是这三种了= =:1.匹配长度归0;2.匹配长度+1;3.匹配长度变为fail[j]+1。

  那么转移方式已经确定啦~接下来就该考虑一下$n\leq 10^9$这个蛋疼的范围了……

  很明显这个范围O(n)是不可能的了= =必须要加速!那么我们来研究一下这个转移:我们可以把$f_i$看作一个向量:$$\begin{bmatrix} f_0 f_1 \cdots f_{m-1} \end{bmatrix}(即0\leq j\leq m-1) $$ 从$f_i$转移到$f_{i+1}$,其实是可以用一个矩阵来表示的: $$ \begin{bmatrix} f_0& f_1 &\cdots &f_{m-1} \end{bmatrix}_{i} * \begin{bmatrix} a_{0,0}& a_{0,1}& \cdots &a_{0,m-1} \\ a_{1,0}& a_{1,1}& \cdots &a_{1,m-1} \\  \ddots& \ddots& \vdots &\ddots \\ a_{m-1,0}& a_{m-1,1}& \cdots &a_{m-1,m-1} \end{bmatrix} = \begin{bmatrix} f_0 &f_1 &\cdots &f_{m-1} \end{bmatrix}_{i+1} $$

  嗯左边的表示$f[i][j]$,右边就是$f[i+1][j]$了;那么a矩阵是什么玩意呢?这是一个转移矩阵:$a[i][j]$表示从匹配了 i 个字符转移到匹配了 j 个字符有多少种方案!很明显当$j>0$的时候f[i][j]只可能是0或1,这里可能需要仔细理解一下,反正$f[i+1]$跟$f[i]$是线性相关的!所以我们可以直接利用矩阵乘法加速!

  嗯这道题我写的时候由于本题有【匹配长度为0】这个状态……然后KMP很久没写过了……果断跪啊,这题貌似是需要在原来的KMP上稍微改动一下,由于我KMP理解的不是很好所以蛋疼了很久……最后是看了Hzwer的写法才过的

 /**************************************************************
Problem: 1009
User: Tunix
Language: C++
Result: Accepted
Time:56 ms
Memory:812 kb
****************************************************************/ //BZOJ 1009
#include<cstdio>
#define rep(i,n) for(int i=0;i<n;++i)
#define F(i,j,n) for(int i=j;i<=n;++i)
const int N=,INF=~0u>>;
/******************tamplate*********************/
int n,m,P;
struct Matrix{
int x[N][N];
int* operator [] (int a) {return x[a];}
Matrix(int a=){
rep(i,N) rep(j,N)
if (i==j) x[i][j]=a;
else x[i][j]=;
}
};
Matrix operator*(Matrix a,Matrix b){
Matrix c;
rep(i,m) rep(j,m) rep(k,m)
c[i][j]=(c[i][j]+a[i][k]*b[k][j])%P;
return c;
}
Matrix Pow(Matrix a,int b){
Matrix r();
for(;b;b>>=,a=a*a) if(b&) r=r*a;
return r;
}
/*******************Matrix**********************/
char s[];
Matrix f,a;
int next[];
void KMP(){
int j=;
F(i,,m){
while (j && s[i]!=s[j+]) j=next[j];
if (s[j+]==s[i]) j++;
next[i]=j;
}
rep(i,m)
rep(j,){
int x=i;
while(x && s[x+]-''!=j) x=next[x];
if (j==s[x+]-'') a[i][x+]++;
else a[i][]++;
}
}
int main(){
scanf("%d%d%d",&n,&m,&P);
scanf("%s",s+);
KMP();
f=Pow(a,n);
int ans=;
rep(i,m) ans+=f[][i],ans%=P;
printf("%d\n",ans);
return ;
}

1009: [HNOI2008]GT考试

Time Limit: 1 Sec  Memory Limit: 162 MB
Submit: 2015  Solved: 1233
[Submit][Status][Discuss]

Description


申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。他的不吉利数学
A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为0

Input

第一行输入N,M,K.接下来一行输入M位的数。 100%数据N<=10^9,M<=20,K<=1000 40%数据N<=1000 10%数据N<=6

Output

阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.

Sample Input

4 3 100
111

Sample Output

81

HINT

Source

[Submit][Status][Discuss]

【BZOJ】【1009】 【HNOI2008】GT考试的更多相关文章

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

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

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

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

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

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

  4. [BZOJ 1009] [HNOI2008] GT考试 【AC自动机 + 矩阵乘法优化DP】

    题目链接:BZOJ - 1009 题目分析 题目要求求出不包含给定字符串的长度为 n 的字符串的数量. 既然这样,应该就是 KMP + DP ,用 f[i][j] 表示长度为 i ,匹配到模式串第 j ...

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

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

  6. BZOJ 1009: [HNOI2008]GT考试(kmp+dp+矩阵优化)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1009 题意: 思路:真的是好题啊! 对于这种题目,很有可能就是dp,$f[i][j]$表示分析到第 ...

  7. bzoj 1009 [HNOI2008]GT考试——kmp+矩阵优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 首先想到 确保模式串不出现 就是 确保每个位置的后缀不是该模式串. 为了dp,需要记录 ...

  8. 题解:BZOJ 1009 HNOI2008 GT考试 KMP + 矩阵

    原题描述: 阿申准备报名参加GT考试,准考证号为N位数 X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai&a ...

  9. bzoj 1009:[HNOI2008]GT考试

    这道题机房n多人好久之前就A了…… 我到现在才做出来…… 一看就是DP+矩阵乘法,但是一开始递推式推错了…… 正确的递推式应该是二维的…… f[i][j] 表示第准考证到第 i 位匹配了 j 位的方案 ...

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

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

随机推荐

  1. Git版本控制工具(一)----git的安装及创建版本库

    ​[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/ ...

  2. AutoIT 实现Firefox上传文件

    Firefox浏览器文件上传代码如下: ;upload file Func _UploadFile($file) AutoItSetOption("WinTitleMatchMode&quo ...

  3. 安装StarUML 及使用时序图(Sequence Diagram)和用例图(use case diagram)

    时序图 用例图

  4. linux运维中的命令梳理(一)

    在linux日常运维中,我们平时会用到很多常规的操作命令. 下面对常用命令进行梳理: 命令行日常系快捷键(不分大小写)CTRL + A 移动光标到行首CTRL + E 移动光标到行末CTRL + U ...

  5. [原创]gerrit上分支操作记录(创建分支、删除分支)

    Git分支对于一个项目的代码管理而言,是十分重要的! 许多久用git的朋友可能已经掌握的很牢固了,但对于一些初涉git的童鞋来说,可能还不是很熟悉. 在此,我将自己的一些操作经历做一梳理,希望能帮助到 ...

  6. 语义化的html结构的好处

    HTML是提供网页文档内容的上下文结构和含义:html本身是没有表现的,我们看到例如<h1>是粗体,字体大小2em,加粗:<strong>是加粗的,不要认为这是html的表现, ...

  7. Python中的sort()方法使用基础

    一.基本形式 sorted(iterable[, cmp[, key[, reverse]]]) iterable.sort(cmp[, key[, reverse]]) 参数解释: (1)itera ...

  8. [转]SIFT特征提取分析

    SIFT(Scale-invariant feature transform)是一种检测局部特征的算法,该算法通过求一幅图中的特征点(interest points,or corner points) ...

  9. OpenGL 4.3配置教程

    OpenGL 4.3配置教程 下载开发包 需要下载的开发包主要包含如下几个组件:freeglut+glew+ OpenGL.Development.Cookbook+源码+GLM+SOIL. Open ...

  10. JDSideMenu实现(整块)侧滑功能,主视图会和状态栏(StatusBar)会一起滑动。

    JDSideMenu 实现侧边菜单功能,支持手势滑动.跟一般的侧边菜单不一样的是,滑动主视图,主视图会和状态栏(StatusBar)会一起滑动. demo 自行下载