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

4 3 100
111

Sample Output

81

HINT

Source

Solution

  $f[i][j]$表示由$i$的数字构成的数串中与不吉利数字刚好匹配$j$位的方案数

  因为我们只需关心后$j$位是否被匹配,如果在不久的将来有一位失配,那么这一段字符就一定不是给定的数串

  可以看出来,由$f[i]$转移到$f[i+1]$时,需要借助$KMP$算出,具体方法就是枚举$0\sim 9$,用$\pi$数组算出匹配的位数$k$,$f[i+1][k]$+=$f[i][j]$

  注意到准考证号位数可以达到$10^9$妈蛋考试时号码都抄不完,$TLE/MLE$无疑

  由于每一次$f[i]$转移到$f[i+1]$时所有步骤是一样的,所以可以用一个矩阵,用乘法代替一次转移。这样就可以用快速幂优化转移啦

  构造矩阵暴力即可,注意$f[i][m]$的特殊性,它每次只向$f[i+1][m]$转移。

 #include <bits/stdc++.h>
using namespace std;
int mod, pi[];
struct matrix
{
int a[][], n, m; matrix() {} matrix(int x, int y)
{
n = x, m = y;
memset(a, , sizeof(a));
} matrix operator* (matrix rhs)
{
matrix ans(n, rhs.m);
for(int i = ; i < n; ++i)
for(int j = ; j < rhs.m; ++j)
for(int k = ; k < m; ++k)
ans.a[i][j] = (ans.a[i][j] + a[i][k] * rhs.a[k][j]) % mod;
return ans;
} matrix operator^ (int rhs)
{
matrix ans(n, n), bs = *this;
for(int i = ; i < n; ++i)
ans.a[i][i] = ;
for(; rhs; rhs >>= , bs = bs * bs)
if(rhs & ) ans = ans * bs;
return ans;
}
};
char s[]; void getpi(int m)
{
int j = ;
for(int i = ; i <= m; ++i)
{
while(j && s[i] != s[j + ])
j = pi[j];
pi[i] = s[i] == s[j + ] ? ++j : j;
}
} int main()
{
int n, m, ans, bs = ;
cin >> n >> m >> mod >> s + ;
getpi(m);
matrix f(, m + ), w(m + , m + );
f.a[][] = , w.a[m][m] = ;
for(int i = ; i < m; ++i)
for(int j = ; j < ; ++j)
{
int k = i;
while(k && j != s[k + ] - )
k = pi[k];
if(j == s[k + ] - ) ++k;
++w.a[i][k];
}
f = f * (w ^ n);
for(ans = ; n; n >>= , bs = (bs * bs) % mod)
if(n & ) ans = (ans * bs) % mod;
cout << (ans - f.a[][m] + mod) % mod << endl;
return ;
}

[BZOJ1009] [HNOI2008] GT考试 (KMP & dp & 矩阵乘法)的更多相关文章

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

    [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...

  2. 【BZOJ-1009】GT考试 KMP+DP+矩阵乘法+快速幂

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

  3. 【BZOJ】1009: [HNOI2008]GT考试(dp+矩阵乘法+kmp+神题)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1009 好神的题orzzzzzzzzzz 首先我是连递推方程都想不出的人...一直想用组合来搞..看来 ...

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

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

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

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

  6. [BZOJ1009][HNOI2008]GT考试(KMP+DP)

    [不稳定的传送门 Solution dp[i][j]表示前i个字符当前匹配到不吉利串的第j个,即当前方案的后缀等于不吉利串前缀 然而由于n过大,不能直接转移,用矩阵优化 Code #include & ...

  7. 洛谷P3193 [HNOI2008]GT考试 kmp+dp

    正解:kmp+dp+矩阵优化 解题报告: 传送门! 啊刚说想做矩阵优化dp的字符串题就找到辣QwQ虽然不是AC自动机的但都差不多嘛QwQ 首先显然可以想到一个dp式?就f[i][j]:凑出i位了,在s ...

  8. [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法

    Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...

  9. BZOJ1009: [HNOI2008]GT考试(KMP+矩阵乘法)

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

随机推荐

  1. 关于CSS的外边距合并问题

    首先,需要明确的是只有普通文档流中块框的垂直外边距才会发生外边距合并.行内框.浮动框或绝对定位之间的外边距不会合并. 而在普通文档流中,这又分两种情况,分别是父子元素之间和相邻元素之间. <!D ...

  2. Maven编译问题

    Maven构建的Project默认使用JDK1.5进行编译,要想使用JDK1.8进行编译,最好在项目的POM文件中加上以下的字段. <build> <plugins> < ...

  3. PHPUnit-附录 B. 标注

    [http://www.phpunit.cn/manual/5.7/zh_cn/appendixes.annotations.html] 所谓标注,是指某些编程语言中允许加在源代码中的一种特殊格式的语 ...

  4. iOS字体名字

    上面我们提到我们需要设置字体集,在IOS系统中我们用到的字体包含一下几种 : Font Family: American Typewriter( AmericanTypewriter,American ...

  5. [POJ 3581]Sequence

    [POJ 3581]Sequence 标签: 后缀数组 题目链接 题意 给你一串序列\(A_i\),保证对于$ \forall i \in [2,n],都有A_1 >A_i$. 现在需要把这个序 ...

  6. Python自动化--语言基础4--模块、文件读写、异常

    模块1.什么是模块?可以理解为一个py文件其实就是一个模块.比如xiami.py就是一个模块,想引入使用就在代码里写import xiami即可2.模块首先从当前目录查询,如果没有再按path顺序逐一 ...

  7. 深入java虚拟机学习 -- 类的加载机制(续)

    昨晚写 深入java虚拟机学习 -- 类的加载机制 都到1点半了,由于第二天还要工作,没有将上篇文章中的demo讲解写出来,今天抽时间补上昨晚的例子讲解. 这里我先把昨天的两份代码贴过来,重新看下: ...

  8. 文本处理三剑客之grep&正则表达式

    grep是一个文本过滤工具,它支持正则表达式,能把搜索匹配到的行打印出来.grep的全称是Global Regular Expression Print(全局正则表达式)使用权限是所有用户. 一.gr ...

  9. ‘true’==true返回false详解

    JavaScript高级程序设计(第3版)  第三章非常完整地解释了原因. 3.5.7 相等操作符 在转换不同的数据类型时,相等和不相等操作符遵循下列基本规则: . 如果有一个操作数是布尔值,则在比较 ...

  10. C#访问修饰符(public,private,protected,internal,sealed,abstract)

    为了控件C#中的对象的访问权限,定义对象时可以在前面添加修饰符. 修饰符有五种:private(私有的),protected(受保护的),internal(程序集内部的),public(公开的),以及 ...