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),他不希望准 ...
随机推荐
- LeetCode 293. Flip Game
原题链接在这里:https://leetcode.com/problems/flip-game/description/ 题目: You are playing the following Flip ...
- How To Uninstall Software Using The Ubuntu Command Line
How To Uninstall Software Using The Ubuntu Command Line Uninstall Ubuntu Software Using The Terminal ...
- 学习动态性能表(7)--v$process
学习动态性能表 第七篇--V$PROCESS 2007.5.30 本视图包含当前系统oracle运行的所有进程信息.常被用于将oracle或服务进程的操作系统进程ID与数据库session之间建立联 ...
- redis之 centos 6.7 下安装 redis-3.2.5
前期准备:1. 操作系统需要安装 gcc 包 与 TCL 库, 通过配置本地 yum 源 ,yum -y install gcc . yum -y install tcl安装2. 下载 redis ...
- fastjson --JSONObject 和JSONArray 转换
fastjson解析:resultValue=[ { "total": 1, "saleLists": [ ...
- Java创建AD(Active Directory)域控制器用户 (未测)
import java.util.Hashtable; import javax.naming.ldap.*; import javax.naming.directory.*; import java ...
- Unix文件指令-Mac终端命令应用
pwd:查看当前文件夹 cd: 打开文件夹 ls:列出当前路径下所有文件 ls -l :列出当前路径下的所有文件详细信息. mkdir: 新建文件夹 touch: 创建文件 eg: touch t ...
- HDU1576(扩展欧几里得)
A/B Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...
- MySQL 5.6 date 与 string 的转换和比较
我们有张表,表中有一个字段 dpt_date ,SQL 类型为 date,表示离开日期. 我们将 dpt_date 与字符串 ‘2016-03-09’ 进行比较,发现效率低于 dpt_date 转换为 ...
- linux参数之max_map_count
“This file contains the maximum number of memory map areas a process may have. Memory map areas are ...