BZOJ1009: [HNOI2008]GT考试(KMP+矩阵乘法)
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位的数。 N<=10^9,M<=20,K<=1000
Output
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.
Sample Input
111
Sample Output
解题思路:
首先,确定一下什么样的数字中没有不吉利数字。
1.这个数字的前缀不是不吉利数字(废话)
2.这个数字中间不包含不吉利数字(废话)
3.这个数字的后缀不是不吉利数字(废话)
那么,这个数字如果是像汉堡那样一层一层堆的话,我们可以通过尽可能阻止不吉利数字出现来完成任务。
假设数字串出现到了第 i 位,只要后缀m-1位不是不吉利数字m-1位就可以。
所以设f[i][j]为数字堆积到 i 而匹配出来了 j 位。
那么 :

a[k][j]为预处理出来的结果,其概念为:
原串中匹配到 j 时 k 位是否可以被枚举,由于做到不重不漏地计数,每次取前一个next即可
最后由于运算简单但递推长度大,使用矩阵乘法即可。
代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
typedef long long lnt;
int n,m;
lnt K;
char num[];
int nxt[];
struct squ{
lnt s[][];
squ friend operator * (squ x,squ y)
{
squ ans;
for(int i=;i<m;i++)
{
for(int j=;j<m;j++)
{
ans.s[i][j]=;
for(int k=;k<m;k++)
{
ans.s[i][j]=(ans.s[i][j]+x.s[i][k]*y.s[k][j])%K;
}
}
}
return ans;
}
squ friend operator ^ (squ x,lnt y)
{
squ ans=x;
y--;
while(y)
{
if(y&)
ans=ans*x;
x=x*x;
y=y/;
}
return ans;
}
}f,g;
int main()
{
scanf("%d%d%lld",&n,&m,&K);
scanf("%s",num+);
nxt[]=nxt[]=;
for(int i=,j=;i<=m;i++)
{
while(j&&num[i]!=num[j+])
j=nxt[j];
if(num[i]==num[j+])
j++;
nxt[i]=j;
}
for(int k=;k<m;k++)
{
for(int j=;j<;j++)
{
int i=k;
while(i&&num[i+]!=j+'')
i=nxt[i];
if(num[i+]==j+'')
i++;
if(i!=m)
g.s[i][k]=(g.s[i][k]+)%K;
}
}
f=g^n;
lnt ans=;
for(int i=;i<m;i++)
{
ans=(ans+f.s[i][])%K;
}
printf("%lld\n",ans);
return ;
}
BZOJ1009: [HNOI2008]GT考试(KMP+矩阵乘法)的更多相关文章
- [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法
Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...
- [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)
Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...
- BZOJ 1009 [HNOI2008]GT考试 (KMP+矩阵乘法)
---恢复内容开始--- 题目大意:给定一个由数字构成的字符串A(len<=20),让你选择一个长度为n(n是给定的)字符串X,一个合法的字符串X被定义为,字符串X中不存在任何一段子串与A完全相 ...
- bzoj1009 [HNOI2008]GT考试——KMP+矩阵快速幂优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串计数DP问题啊...连题解都看了好多好久才明白,别提自己想出来的蒟蒻我... 首 ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
- BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法
BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法 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 ...
- bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...
- 题解:BZOJ 1009 HNOI2008 GT考试 KMP + 矩阵
原题描述: 阿申准备报名参加GT考试,准考证号为N位数 X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai&a ...
随机推荐
- javascript进阶课程--第一章--函数
javascript进阶课程--第一章--函数 学习要点 了解内存管理 掌握全局函数的使用 知识点 基本类型和引用类型 基本类型值有:undefined,NUll,Boolean,Number和Str ...
- POJ 3257 DP
题意: 思路: 用vector存上本出发点能到的地方&成本&有趣指数(用结构体保存) 然后DP就好了 f[i][j]表示到了i 成本为j的有趣指数最大是多少 f[vec[i][k].e ...
- Java经典算法案例
笔试中的编程题3 JAVA经典算法40例[程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? ...
- Vim使用心得总结
基本快捷键 v 进入可视模式 i / a 光标前/后插入模式 I / A 行首/末插入模式 Crtl+c 进入命令模式 Crtl+v 进入块可视模式 Q 进入EX模式 gh 进入选择模式 u 撤销 U ...
- JS 引擎基础之 Shapes and Inline Caches
阅读下面这篇文章,需要20分钟: 一起了解下 JS 引擎是如何运作的吧! JS 的运作机制可以分为 AST 分析.引擎执行两个步骤: JS 源码通过 parser(分析器)转化为 AST(抽象语法树) ...
- JS的解析与执行过程—函数预处理
声明:之所以分为全局预处理与函数预处理,只是为了理解方便,其实在实际运行中二者是不分先后的. 函数预处理阶段与全局预处理的差别: 函数每调用一次,就会产生一个LexicalEnviroment对象,在 ...
- JS取出两个数组的不同或相同元素
JS合并两个数组的方法 我们在项目过程中,有时候会遇到需要将两个数组合并成为一个的情况.比如: var a = [1,2,3]; var b = [4,5,6]; 有两个数组a.b,需求是将两个数组合 ...
- CMD规范学习笔记——基于SEAJS实现
CMD(Common Module Definition):该规范明确了模块的书写格式和基本交互规则.通常一个模块就是一个JS文件. 通过define关键字来定义模块,最基本的格式为: define( ...
- Innodb锁的类型
Innodb锁的类型 行锁(record lock) 行锁总是对索引上锁,如果某个表没有定义索引,mysql就会使用默认创建的聚集索引,行锁有S锁和X锁两种类型. 共享锁和排它锁 Innodb锁有两种 ...
- STM32CUBEF4 实现USB 虚拟串口
一.stm32cubemx 生成工程后USB转串口出现黄色感叹号的问题 如下图所示,在stm32cubemx工程中选择usb转串口功能Communication Device Class (Virtu ...