题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009

首先想到 确保模式串不出现 就是 确保每个位置的后缀不是该模式串。

为了dp,需要记录第 i 个位置的后缀已经有几位和模式串的前几位吻合了。

所以想到可以转移到 j+1 或 0 。

但其实不一定是0,因为可能和前面的接上。这里就要用kmp了!

注意可以和很多位置接上的时候,应该和最长的那个接上,而不是和每个 nxt 都接上,也不是什么能选择的。

知道了当前 j 能转移到哪些 j ,就可以矩阵优化了。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=;
int n,m,mod,nxt[N],prn,ch[N];
struct Matrix{
int a[N][N];
Matrix(){memset(a,,sizeof a);}
Matrix operator * (const Matrix &b)const
{
Matrix c;
for(int i=;i<m;i++)//<m is enough
for(int k=;k<m;k++)
for(int j=;j<m;j++)
(c.a[i][j]+=a[i][k]*b.a[k][j]%mod)%=mod;
return c;
}
}r,ans;
void getnxt()
{
for(int i=;i<=m;i++)//i=2,or nxt[1]=1
{
int k;
for(k=nxt[i-];ch[k+]!=ch[i]&&k;k=nxt[k]);
nxt[i]=k+(ch[k+]==ch[i]);
}
for(int i=;i<m;i++)//i=0 //<m is enough
{
for(int j=;j<=;j++)
{
int k;
for(k=i;k&&ch[k+]!=j;k=nxt[k]);//k=i!!
if(ch[k+]==j)r.a[i][k+]++;//only keep 1,keep the longest
else r.a[i][]++;
// if(ch[k+1]==j)r.a[i][k+1]++;
// if(ch[1]==j)r.a[i][1]++;// when k=0
// else r.a[i][0]++;//
}
// if(i&&i!=m)r.a[i][i+1]++;//don't forget, and i!=0
}
}
int main()
{
scanf("%d%d%d",&n,&m,&mod);
for(int i=;i<=m;i++)scanf("%1d",&ch[i]);
getnxt();
// for(int i=0;i<m;i++)ans.a[i][i]=1;//!!
ans.a[][]=;
while(n){if(n&)ans=ans*r;r=r*r;n>>=;}
for(int i=;i<m;i++)(prn+=ans.a[][i])%=mod;
printf("%d\n",prn);
return ;
}

bzoj 1009 [HNOI2008]GT考试——kmp+矩阵优化dp的更多相关文章

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

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

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

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

  3. BZOJ 1009 [HNOI2008]GT考试 (KMP+矩阵乘法)

    ---恢复内容开始--- 题目大意:给定一个由数字构成的字符串A(len<=20),让你选择一个长度为n(n是给定的)字符串X,一个合法的字符串X被定义为,字符串X中不存在任何一段子串与A完全相 ...

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

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

  5. 洛谷P3193 GT考试 kmp+矩阵优化dp

    题意 求\(N\)位数字序列(可以有前导0)中不出现某\(M\)位子串的个数,模\(K\). \(N<=10^9,M<=20,K<=1000\) 分析 设\(dp[i][j]\)表示 ...

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

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

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

    题目链接 设f[i][j]为当前是第i位考号.现在匹配到第j位(已有j-1位和A[]匹配)的方案数 因为假如当前匹配j位,如果选择的下一位与A[j+1]不同,那么新的匹配位数是fail[j]而不是0, ...

  8. bzoj1009 GT考试 (kmp+矩阵优化dp)

    设f[i][j]是到第i位 已经匹配上了j位的状态数 然后通过枚举下一位放0~9,可以用kmp处理出一个转移的矩阵 然后就可以矩阵快速幂了 #include<bits/stdc++.h> ...

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

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

随机推荐

  1. 【HackerRank】Lonely Integer

    There are N integers in an array A. All but one integer occur in pairs. Your task is to find out the ...

  2. Tooltip表单验证的注册表单

    在线演示 本地下载

  3. awk的逻辑运算符

    运算符 描述 赋值运算符 = += -= *= /= %= ^= **= 赋值语句 逻辑运算符 || 逻辑或 && 逻辑与 正则运算符 ~ ~! 匹配正则表达式和不匹配正则表达式 关系 ...

  4. PHP面向对象之对象和引用

    在PHP中对象类型和简单变量类型表现可以说是大相径庭,很多数据类型都要可以在写时进行复制,如当写代码$a=$b时,两个变量因为赋予相同的值而告终.所以需要注意的是,这种情况用在对象时就会完全不同了. ...

  5. win10打不开菜单且点击通知栏无反应的解决方法

    1.在键盘上按下win+R键,或在开始菜单图标上点击右键选择"运行" 2.输入powershell,按下“确定”运行 3.在窗口里输入或复制粘贴以下命令,注意只有一行: Get-A ...

  6. gdoi2017爆零记

    前言 这次gdoi,用三个词来形容我:爆零+爆零+爆零.本来还希望能在gdoi搞个小新闻(拿个一等什么的). Day0 这次gdoi是在东莞东华中学,坐个动车下午3点多就到了,然后打个滴滴去酒店(本来 ...

  7. CodeForces 266E More Queries to Array...(线段树+式子展开)

    开始觉得是规律题的,自以为是的推了一个规律,结果测试数据都没过....看了love神的博客才发现只是把式子展开就找到规律了.不过挺6的是我虽然想错了,但是维护的的东西没有错,只是改改(改了进两个小时好 ...

  8. SQl查询基础

    SQL语言是一门简单易学却又功能强大的语言,他让你快速上手并写出比较复杂的查询语句,但对于大多数开发者来书,使用SQL查询数据库并没有一个抽象的过程和一个合理的步骤,这很可能会是在写一些特定的查询语句 ...

  9. Ubuntu 没有mkinitrd 解决方法

    1. 先apt-get install  先装cramfsprogs 2. http://archive.debian.net/zh-cn/sarge/initrd-tools 下载initrd-to ...

  10. struts2常见配置解决错误There is no mapped for namespace[/] and action name

    我碰到这个错误的原因是我把配置文件名写成了Struts.xml,改成struts.xml就可以了. 在确定struts.xml本身并没有写错的情况下,那么发生错误有可能是路径,配置文件名. 如果实在找 ...