题意:

求长度为n的不含长为m的指定子串的字符串的个数

1s, n<=1e9, m<=50

思路:

长见识了。。

设那个指定子串为s

f[i][j]表示长度为i的字符串(其中后j个字符与s的前j个字符一致的情况下)的方法数

若匹配到s串长度为i的后缀加一个字符num可以组成最长长度为j的后缀,设a[i][j]为num的方法数

例如,s为12312,a为

9 1 0 0 0 0
8 1 1 0 0 0
8 1 0 1 0 0
9 0 0 0 1 0
8 1 0 0 0 1

(i,j都是从0到m-1)

如a[1][2]表示从“1”到“12”可以加的字符方法数,显然加“2”才可以,所以a[1][2]=1

而a[2][0]表示从“12”到“”可以加的字符方法数:显然不能加“3”,不然s串会匹配到"123";也不能加“1”,不然s串会匹配成"1"。所以a[2][0]=8

求a矩阵的方法是kmp,感觉只可意会(我写不出来QAQ)

显然f[i][x]只能由f[i-1][k]转移而来,而k为多少,要看a数组了

然后状态转移方程为:$f[i][j] = f[i-1][0]*a[0][j]+f[i-1][1]*a[1][j] +\dots + f[i-1][m-1]*a[m-1][j]$

这个状态转移方程可以用矩阵快速幂来加速

答案就是$\sum f[n][i]$

代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<stack>
#include<queue>
#include<deque>
#include<set>
#include<vector>
#include<map>
#include<functional> #define fst first
#define sc second
#define pb push_back
#define mem(a,b) memset(a,b,sizeof(a))
#define lson l,mid,root<<1
#define rson mid+1,r,root<<1|1
#define lc root<<1
#define rc root<<1|1
#define lowbit(x) ((x)&(-x)) using namespace std; typedef double db;
typedef long double ldb;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> PI;
typedef pair<ll,ll> PLL; const db eps = 1e-;
//const int mod = 1e9+7;
const int maxn = 2e3+;
const int maxm = 2e6+;
const int inf = 0x3f3f3f3f;
const db pi = acos(-1.0); int a[][];
int f[][];
int n, m, mod;
char s[maxn];
int Next[maxn]; void mtpl(int a[][], int b[][], int s[][]){
int tmp[][];
for(int i = ; i < m; i++){
for(int j = ; j < m; j++){
tmp[i][j] = ;
for(int k = ; k < m; k++){
tmp[i][j]+=a[i][k]*b[k][j]%mod;
tmp[i][j]%=mod;
}
}
}
for(int i = ; i < m; i++){
for(int j = ; j < m; j++){
s[i][j] = tmp[i][j];
}
}
return;
} void fp(int x){
while(x){
if(x&)mtpl(f,a,f);
mtpl(a,a,a);
x>>=;
}
return;
} void kmp(){
int fix = ;
for(int i = ; i <= m; i++){
while(fix && s[fix+]!=s[i])fix=Next[fix];
if(s[fix+]==s[i])++fix;
Next[i]=fix;
} for(int i = ; i < m; i++){
for(char j = ''; j <= ''; j++){
fix = i;
while(fix&&s[fix+]!=j)fix=Next[fix];
if(j==s[fix+])a[i][fix+]++;
else a[i][]++;
}
}
return;
} int main(){
scanf("%d %d %d", &n, &m, &mod);
scanf("%s", s+);
mem(a, );
kmp();
mem(f,);
f[][]=;
fp(n);
int ans = ;
for(int i = ; i < m; i++){
ans += f[][i];
ans%=mod;
}
printf("%d", ans);
return ;
}
/*
5
3 4 5 1 2
*/

BZOJ 1009 [HNOI2008]GT考试(矩阵快速幂优化DP+KMP)的更多相关文章

  1. 【bzoj1009】[HNOI2008]GT考试(矩阵快速幂优化dp+kmp)

    题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 这道题一看数据范围:$ n<=10^9 $,显然不是数学题就是矩乘快速幂优 ...

  2. 2018.10.23 bzoj1297: [SCOI2009]迷路(矩阵快速幂优化dp)

    传送门 矩阵快速幂优化dp简单题. 考虑状态转移方程: f[time][u]=∑f[time−1][v]f[time][u]=\sum f[time-1][v]f[time][u]=∑f[time−1 ...

  3. 2018.10.22 bzoj1009: [HNOI2008]GT考试(kmp+矩阵快速幂优化dp)

    传送门 f[i][j]f[i][j]f[i][j]表示从状态"匹配了前i位"转移到"匹配了前j位"的方案数. 这个东西单次是可以通过跳kmp的fail数组得到的 ...

  4. 2018.10.16 uoj#340. 【清华集训2017】小 Y 和恐怖的奴隶主(矩阵快速幂优化dp)

    传送门 一道不错的矩阵快速幂优化dpdpdp. 设f[i][j][k][l]f[i][j][k][l]f[i][j][k][l]表示前iii轮第iii轮还有jjj个一滴血的,kkk个两滴血的,lll个 ...

  5. 省选模拟赛 Problem 3. count (矩阵快速幂优化DP)

    Discription DarrellDarrellDarrell 在思考一道计算题. 给你一个尺寸为 1×N1 × N1×N 的长条,你可以在上面切很多刀,要求竖直地切并且且完后每块的长度都是整数. ...

  6. bzoj1009 [HNOI2008]GT考试——KMP+矩阵快速幂优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串计数DP问题啊...连题解都看了好多好久才明白,别提自己想出来的蒟蒻我... 首 ...

  7. BZOJ 1009 [HNOI2008]GT考试 ——矩阵乘法 KMP

    先用KMP处理所有的转移,或者直接暴力也可以. 然后矩阵快速幂即可. #include <cstdio> #include <cstring> #include <ios ...

  8. 2019.02.11 bzoj4818: [Sdoi2017]序列计数(矩阵快速幂优化dp)

    传送门 题意简述:问有多少长度为n的序列,序列中的数都是不超过m的正整数,而且这n个数的和是p的倍数,且其中至少有一个数是质数,答案对201704082017040820170408取模(n≤1e9, ...

  9. 2018.11.08 NOIP模拟 景点(倍增+矩阵快速幂优化dp)

    传送门 首先按照题意构造出转移矩阵. 然后可以矩阵快速幂求出答案. 但是直接做是O(n3qlogm)O(n^3qlogm)O(n3qlogm)的会TTT掉. 观察要求的东西发现我们只关系一行的答案. ...

随机推荐

  1. C#多线程与异步

    1.什么是异步同步 如果一个方法被调用,调用者需要等待该方法被执行完毕之后才能继续执行,则是同步. 如果方法被调用后立刻返回,即使该方法是一个耗时操作,也能立刻返回到调用者,调用者不需要等待该方法,则 ...

  2. Numpy的介绍与基本使用方法

    1.什么是Numpy numpy官方文档:https://docs.scipy.org/doc/numpy/reference/?v=20190307135750 NumPy是一个功能强大的Pytho ...

  3. qiniuLive 连麦流程介绍

    本文出自APICloud官方论坛 qiniuLive 封装了七牛直播云服务平台的移动端开放 SDK.该模块包括视频流采集和视频流播放两部分 iOS连麦流程图: Android连麦流程图: 以下部分代码 ...

  4. 树形dp - 求树的直径

    随着杭州西湖的知名度的进一步提升,园林规划专家湫湫希望设计出一条新的经典观光线路,根据老板马小腾的指示,新的风景线最好能建成环形,如果没有条件建成环形,那就建的越长越好. 现在已经勘探确定了n个位置可 ...

  5. 线性基 - 寻找异或第K大

    XOR is a kind of bit operator, we define that as follow: for two binary base number A and B, let C=A ...

  6. 对标Eureka的AP一致性,Nacos如何实现Raft算法

    一.快速了解Raft算法 Raft 适用于一个管理日志一致性的协议,相比于 Paxos 协议 Raft 更易于理解和去实现它. 为了提高理解性,Raft 将一致性算法分为了几个部分,包括领导选取(le ...

  7. Nginx作为web静态资源服务器——防盗链

    ​ 基于http_refer防盗链配置模块 Syntax:valid_referers none | blocked | server_names | string ...; Default:—— C ...

  8. 生产者消费者代码学习,Producer_Consuner

    使用BlockingQuery实现生产者者消费者:考虑并发,解耦. 生产者消费者模式是面向过程的设计模式. 生产者制造数据   ------> 生产者把数据放入缓冲区  -------> ...

  9. 编程基础系列--之--浅谈List、Set、Map和泛型(一)——单列集合

    之前在学习Java时对于泛型,集合的理解一直模模糊糊,随着时间的推移,对泛型和集合有了一些浅显的认知,打算写出来巩固一下,也希望各位大佬能指出理解不当之处,万分感谢!!! 在Java语言中,集合分为两 ...

  10. 学习 lind layerdiagram 第三弹