BZOJ1009

妙!

推荐这篇题解: https://www.luogu.org/blog/Edgration/solution-p3193

考虑设计dp,设$f_{i, j}$表示长串匹配到i,短串匹配到j的方案数,初值有$f_{0,0} = 1$

    那么最后的答案   $ans = \sum_{i = 0}^{m - 1} f_{n,i}$

考虑转移,假设当前填到第i位,有一种填法能使$f_{i,j}$转移到$f_{i + 1, j + 1}$,那么填剩下的数字全部都转移到$f_{i + 1,0}$吗?

错!这就是一开始想错的地方,填不一样的数字并不一定是转移到0的匹配位置,而是考虑转移到以j结尾的后缀的最长前缀!

设$g_{i, j}$表示从i的匹配长度转移到j的匹配长度的方案数,有转移:

      $f_{i, j} = \sum_{k = 0}^{m - 1}f_{i - 1, k} * g_{k, j}$

因为给出的短串是恒定的,所以g数组的值也是恒定的,而找与后缀相匹配的最长前缀,肯定是想到kmp啦

然而这样还是不足以通过本题,再次观察这个方程,发现这就是一个矩阵乘法的形式,相当于把f看成一个1*m的矩阵F,把g看成一个m*m的转移矩阵G。

      $F' = F * G^{n}$ 用G转移Fn次

到此为止,本题全部解决,时间复杂度$O(m^{2}logn)$

Code:

#include <cstdio>
#include <cstring>
using namespace std; const int N = ; int n, m, P, nxt[N], mat[N][N];
char str[N]; inline void prework() {
nxt[] = nxt[] = ;
for(int i = , j = ; i <= m; i++) {
for(; j > && str[i] != str[j + ]; j = nxt[j]);
if(str[i] == str[j + ]) j++;
nxt[i] = j;
} for(int i = ; i < m; i++) {
for(int j = ''; j <= ''; j++) {
int tmp = i;
for(; tmp > && str[tmp + ] != j; tmp = nxt[tmp]);
if(str[tmp + ] == j) tmp++;
if(tmp < m) mat[i][tmp]++;
}
}
} inline void work(int &x, int y) {
x = (x + y % P) % P;
} struct Matrix {
int s[N][N]; inline void init() {
memset(s, , sizeof(s));
} friend Matrix operator * (const Matrix &x, const Matrix &y) {
Matrix res;
res.init();
for(int i = ; i < m; i++)
for(int j = ; j < m; j++)
for(int k = ; k < m; k++)
work(res.s[i][j], x.s[i][k] * y.s[k][j]);
return res;
} inline Matrix pow(int y) {
Matrix res = *this, x = *this;
for(y--; y > ; y >>= ) {
if(y & ) res = res * x;
x = x * x;
}
return res;
} } f, g; int main() {
scanf("%d%d%d", &n, &m, &P);
scanf("%s", str + );
prework(); for(int i = ; i < m; i++)
for(int j = ; j < m; j++)
g.s[i][j] = mat[i][j];
g = g.pow(n); f.s[][] = ; f = f * g; int ans = ;
for(int i = ; i < m; i++)
work(ans, f.s[][i]);
printf("%d\n", ans); return ;
}

Luogu 3193 [HNOI2008]GT考试的更多相关文章

  1. luogu P3193 [HNOI2008]GT考试

    传送门 单串匹配显然用\(kmp\) 一个暴力的dp是设\(f_{i,j}\),表示前\(i\)位,正在匹配给定串第\(j\)位的方案,转移就枚举下一位放什么,然后使用\(kmp\)看会匹配到给定串的 ...

  2. [HNOI2008]GT考试(kmp,dp,矩阵乘法)

    [HNOI2008]GT考试(luogu) Description 求有多少个n位的数字串不包含m位的字符串(范围 n <= 1e9 n<=1e9, m <= 20m<=20) ...

  3. 1009: [HNOI2008]GT考试

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

  4. 【bzoj1009】[HNOI2008]GT考试

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

  5. BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...

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

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

  7. [HNOI2008] GT考试

    [HNOI2008] GT考试 标签 : DP 矩阵乘法 题目链接 题意 n位数中不出现一个子串的方案数. 题解 \(设dp[i][j]\)为前i位匹配到j时的合法方案数.(所谓合法,就是不能有别的匹 ...

  8. BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法

    BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考 ...

  9. BZOJ1009 [HNOI2008]GT考试 矩阵

    去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...

随机推荐

  1. Zeroc Ice 负载均衡之Icegrid simple

    最近学习Icestorm的replicated例子,在本地计算机上面跑通了,但在两台机器上(一台服务器192.168.0.113,一台客户端192.168.0.188),怎么都跑不通.上网求助,大家给 ...

  2. awk指令的使用

    awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大 awk工作流程是这样的:读入有'\n'换行符分割的一条记录,然后将记录按指定的域分隔 ...

  3. UVALive - 3490 Generator (AC自动机+高斯消元dp)

    初始有一个空串s,从前n个大写字母中不断随机取出一个字母添加到s的结尾,出现模式串t时停止,求停止时s的长度期望. 这道题解法不唯一,比较无脑的方法是对模式串t建一个单串AC自动机,设u为自动机上的一 ...

  4. tableau学习笔记—1

    第一部分 第一章 数据可视化 1.1 用数据讲故事 1.2 数据不只是数字 1.3 在数据中寻找什么(关系.模式.异常) 第二章 Tableau概述 2.1 Tableau概述 2.2 产品简介 第三 ...

  5. [ Laravel 5.5 文档 ] 处理用户请求 —— HTTP 请求的过滤器:中间件

    [ Laravel 5.5 文档 ] 处理用户请求 —— HTTP 请求的过滤器:中间件 http://laravelacademy.org/post/7812.html 简介 中间件为过滤进入应用的 ...

  6. bzoj 4827 [Hnoi2017]礼物——FFT

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4827 式子就是 \sum_{i=0}^{n-1}(a[ i ] - b[ i+k ] + c ...

  7. 【转】 Pro Android学习笔记(七八):服务(3):远程服务:AIDL文件

    目录(?)[-] 在AIDL中定义服务接口 根据AIDL文件自动生成接口代码 文章转载只能用于非商业性质,且不能带有虚拟货币.积分.注册等附加条件.转载须注明出处:http://blog.csdn.n ...

  8. Java-API-Package:java.lang

    ylbtech-Java-API-Package:java.lang 1.返回顶部 1. Package java.lang Provides classes that are fundamental ...

  9. python学习笔记(一):python简介和入门

    最近重新开始学习python,之前也自学过一段时间python,对python还算有点了解,本次重新认识python,也算当写一个小小的教程.一.什么是python?python是一种面向对象.解释型 ...

  10. hibernate 事务的隔离级别

    脏读不可重复读幻读可序列化(符合事务的四个特性的正常情况 ) 解释: 脏读:事务A对数据1做了更新,但是还没有来得及提交 此时事务B对数据1进行了查询获得了事务A更新后的数据, 但是事务A因为一些原因 ...