Luogu 3193 [HNOI2008]GT考试
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考试的更多相关文章
- luogu P3193 [HNOI2008]GT考试
传送门 单串匹配显然用\(kmp\) 一个暴力的dp是设\(f_{i,j}\),表示前\(i\)位,正在匹配给定串第\(j\)位的方案,转移就枚举下一位放什么,然后使用\(kmp\)看会匹配到给定串的 ...
- [HNOI2008]GT考试(kmp,dp,矩阵乘法)
[HNOI2008]GT考试(luogu) Description 求有多少个n位的数字串不包含m位的字符串(范围 n <= 1e9 n<=1e9, m <= 20m<=20) ...
- 1009: [HNOI2008]GT考试
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数\(X_1X_ ...
- 【bzoj1009】[HNOI2008]GT考试
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3018 Solved: 1856[Submit][Statu ...
- BZOJ_1009_[HNOI2008]_GT考试_(动态规划+kmp+矩阵乘法优化+快速幂)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串全部由0~9组成,给出一个串s,求一个长度为n的串,不包含s的种类有多少. 分析 ...
- BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )
写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...
- [HNOI2008] GT考试
[HNOI2008] GT考试 标签 : DP 矩阵乘法 题目链接 题意 n位数中不出现一个子串的方案数. 题解 \(设dp[i][j]\)为前i位匹配到j时的合法方案数.(所谓合法,就是不能有别的匹 ...
- BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法
BZOJ_1009_[HNOI2008]GT考试_KMP+矩阵乘法 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考 ...
- BZOJ1009 [HNOI2008]GT考试 矩阵
去博客园看该题解 题目 [bzoj1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn(0<=Xi<=9),他不希望准 ...
随机推荐
- python_安装python2.7.7和easy_install
[环境]: WIN7 + 32位 [要求]: 安装python2.7.7, easy_install 1. 下载并安装python2.7.7 首先访问http://www.python.org/dow ...
- IEflash遇到flash遮挡
遇到IE中(包括IE6+)弹窗广告要flash遮挡的问题,后来想到了常用的iframe方法(参见<解决IE6 select z-index无效,遮挡div的bug>),最终成功了flash ...
- wordpress 插件 汉化
http://blog.wpjam.com/article/localizing-a-wordpress-plugin-using-poedit/ 翻译或者说本地化 WordPress 插件和主题可以 ...
- MySql数据库中存放用户密码需要注意什么?
前几天被电话面试了,问了一些比较实际的问题,其中一个问题关于PHP开发中MySql里存放用户密码需要注意什么,由于没有过大项目经验,一时语塞,回来网上找了找记下来,希望能对其他人有帮助,我也继续学习. ...
- 2017-2018-1 20179215《Linux内核原理与分析》第十周作业
第17章 设备与模块 一.设备类型 除了以上3种典型的设备之外,其实Linux中还有一些其他的设备类型,其中见的较多的应该算是"伪设备".所谓"伪设备",其实 ...
- [SPOJ10707]Count on a tree II
luogu 题意 给定一个n个节点的树,每个节点表示一个整数,问u到v的路径上有多少个不同的整数. sol 也就是路径数颜色.树上莫队板子题. 我这种分块的姿势貌似是假的. 所以跑的是最慢的QAQ. ...
- python数据类型,int,str,bool
一,python中的int() int在python中主要用来运算,对字符串的转化,用int(str)表示,并且需要str.isdigit为真. 在int()中二进制的转换如下: #bit_lengt ...
- vc++2008 采用GSoap访问 WebService
(转http://www.cppblog.com/yeqing/articles/12762.html) 前一阶段写gSOAP 的文章没保存好,后来想写的,越学越没有写的勇气了,感觉自己很菜,但是现在 ...
- 设置Qt应用程序图标及应用程序名 【转载】
一直以来很纠结给qt应用程序添加图标问题,在网上收过一次,但是感觉不够完整,现将自己的实现过程记录下,以便以后查看: 通过网上的例子知道qt助手中有相关说明: Setting the Applicat ...
- Redis 分布式锁 - 分布式锁的正确实现方式
前言 分布式锁一般有三种实现方式:1. 数据库乐观锁:2. 基于Redis的分布式锁:3. 基于ZooKeeper的分布式锁.本篇博客将介绍第二种方式,基于Redis实现分布式锁.虽然网上已经有各种介 ...