题意

  • 求\(N\)位数字序列(可以有前导0)中不出现某\(M\)位子串的个数,模\(K\)。
  • \(N<=10^9,M<=20,K<=1000\)

分析

设\(dp[i][j]\)表示匹配串下标\(i\)匹配到模式串下标\(j\)时,满足要求的方案数;枚举匹配串的下一位是0~9中哪个数,若原先匹配串最远能匹配到模式串的下标为\(k\),加入这个数后最远能匹配到模式串的下标为\(j\),设\(a[k][j]\)为将匹配模式串下标从\(k\)变为\(j\)的数字个数,可以用\(next\)数组求出,dp转移方程就变成了

\[dp[i][j]=\sum_{k=0}^{m-1}dp[i][k]*a[k][j]
\]

这个式子可以用矩阵优化。

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define pb push_back
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=1e5+10;
int n,m,p,nex[21];
char s[21];
ll a[20][20],ret[20][20];
int find(int j,char k){
while(j&&s[j+1]!=k) j=nex[j];
if(k==s[j+1]) ++j;
return j;
}
void mul(ll a[20][20],ll b[20][20]){
ll tmp[20][20]={0};
for(int i=0;i<m;i++)
for(int j=0;j<m;j++)
for(int k=0;k<m;k++)
tmp[i][j]=(tmp[i][j]+a[i][k]*b[k][j]%p)%p;
for(int i=0;i<m;i++) for(int j=0;j<m;j++) a[i][j]=tmp[i][j];
}
void ksm(ll b){
for(int i=0;i<m;i++) ret[i][i]=1;
while(b){
if(b&1) mul(ret,a);
mul(a,a);
b>>=1;
}
}
int main(){
//ios::sync_with_stdio(false);
//freopen("in","r",stdin);
scanf("%d%d%d",&n,&m,&p);
scanf("%s",s+1);
for(int i=2,j=0;i<=m;i++){
while(j&&s[i]!=s[j+1]) j=nex[j];
if(s[i]==s[j+1]) ++j;
nex[i]=j;
}
for(int j=0;j<m;j++){
for(char k='0';k<='9';k++){
a[j][find(j,k)]++;
}
}ksm(n);
ll ans=0;
for(int i=0;i<m;i++){
ans=(ans+ret[0][i])%p;
}
printf("%lld\n",ans);
return 0;
}

洛谷P3193 GT考试 kmp+矩阵优化dp的更多相关文章

  1. bzoj 1009 [HNOI2008]GT考试——kmp+矩阵优化dp

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 首先想到 确保模式串不出现 就是 确保每个位置的后缀不是该模式串. 为了dp,需要记录 ...

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

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

  3. 洛谷P2365 任务安排(斜率优化dp)

    传送门 思路: 最朴素的dp式子很好考虑:设\(dp(i,j)\)表示前\(i\)个任务,共\(j\)批的最小代价. 那么转移方程就有: \[ dp(i,j)=min\{dp(k,j-1)+(sumT ...

  4. 洛谷P2120 [ZJOI2007]仓库建设 斜率优化DP

    做的第一道斜率优化\(DP\)QwQ 原题链接1/原题链接2 首先考虑\(O(n^2)\)的做法:设\(f[i]\)表示在\(i\)处建仓库的最小费用,则有转移方程: \(f[i]=min\{f[j] ...

  5. 【洛谷p3994】Highway 二分+斜率优化DP

    题目大意:给你一颗$n$个点的有根树,相邻两个点之间有距离,我们可以从$x$乘车到$x$的祖先,费用为$dis\times P[x]+Q[x]$,问你除根以外每个点到根的最小花费. 数据范围:$n≤1 ...

  6. 洛谷4072 SDOI2016征途 (斜率优化+dp)

    首先根据题目中给的要求,推一下方差的柿子. \[v\times m^2 = m\times \sum x^2 - 2 \times sum \times sum +sum*sum \] 所以\(ans ...

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

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

  8. 洛谷模拟NOIP考试反思

    洛谷模拟NOIP考试反思 想法 考了这么简单的试qwq然而依然emmmmmm成绩不好 虽然本次难度应该是大于正常PJ难度的但还是很不理想,离预估分数差很多qwq 于是就有了本反思嘤嘤嘤 比赛链接 原比 ...

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

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

随机推荐

  1. springboot打包的jar项目,不需要安装jdk环境启动

    因为服务器上是JDK7,而springboot至少用JDK8才行,但是又因为是很老的项目,不是很清楚能不能换JDK8,有风险,因此选择以前项目用JDK7,而新的springboot用JDK8.步骤一: ...

  2. 数据结构-二叉搜索树Java实现

    1,Node.java 生成基础二叉树的结构 package com.cnblogs.mufasa.searchTree; /** * 节点配置父+左+右 */ public class Node{ ...

  3. 8 java 笔记

    1 import语句可以简化编程,可以导入指定包下面的某个类或者全部类 2 java.lang,Object类是所有类的父类,要么是其直接父类,要么是其间接父类 3 子类扩展了父类,子类是一种特殊的父 ...

  4. 第十三章、元类(metaclass)

    目录 第十三章.元类(metaclass) 一.什么是元类 二.为什么用元类 第十三章.元类(metaclass) 一.什么是元类 在python中一切皆对象,那么我们用class关键字定义的类本身也 ...

  5. Python学习记录1-基础知识

    基础知识 基础 #简单记录了部分基础知识 #普通的打印字符串 >>> print("hello world") hello world ------------- ...

  6. hadoop--大数据生态圈中最基础、最重要的组件

    hadoop是什么? hadoop是一个由Apache基金会所开发的分布式系统基础架构,hdfs分布式文件存储.MapReduce并行计算.主要是用来解决海量数据的存储和海量数据的分析计算问题,这是狭 ...

  7. stm32WB 笔记

    1.HAL Debug functions(调试功能) 可以在不同模式下使能或者失能调试器 This section provides functions allowing to:• Enable/D ...

  8. 严格次小生成树[BJWC2010]

    原文必点 原题链接 题目描述 给定一张\(N\) 个点$ M $条边的无向图,求无向图的严格次小生成树. 设最小生成树的边权之和为\(sum\),严格次小生成树就是指边权之和大于\(sum\)的生成树 ...

  9. 网络协议相关面试问题-TCP与IP网络模型

    互联网应用的实现主要是通过分层来实现的,每一层有自己相应的功能,上层依赖于下层,具体层次如下图: 下面具体一层层来了解: 物理层 / 实体层: 也就是将电脑通过物理的手段连接起来,其实也就是01电子信 ...

  10. Python 学习第一天(二)python 入门

    1.第一个python程序 1.1 直接打印输出 打开cmd,输入python进入到python交互式环境:(看到>>>是在Python交互式环境下:) 在python交互环境下输入 ...