题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009

字符串计数DP问题啊...连题解都看了好多好久才明白,别提自己想出来的蒟蒻我...

首先要设计一个不太好想的状态:f[i][j]表示大串上到第 i 位时有小串前 j 位的后缀,且不包含整个小串的方案数;

也就是如果小串是 12312 , f[5][3] 表示目前大串的情况是 **123... ;

这个状态要从 i 转移到 i+1 ,还需要一个帮助它的数组 a,a[i][j]表示在长度为 i 的后缀后面加一个数字能变成长度为 j 的后缀的方案数;

也就是说,对于 12312,从0到4的 a 数组应该如下:

9 1 0 0 0

8 1 1 0 0

8 1 0 1 0

9 0 0 0 1

8 1 0 0 0

a 数组的定义可以联想到 kmp 算法,事实上它就是通过 kmp 算法的 nxt 数组求得;

于是就可以得到转移方程:f[i][j] = ∑(0<=k<m) f[i-1][k] * a[k][j]

然后发现对于每一步,进行的转移都是相同的;

所以可以用矩阵快速幂来优化,转移矩阵就是 a 数组;

看了好多好多博客才明白...

这篇博客写得很好:https://blog.csdn.net/loi_dqs/article/details/50897662

尤其是代码真的简洁!所以模仿着写了。

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef long long ll;
int n,m,mod,nxt[],sum;
char s[];
struct Matrix{
int n,m,a[][];
Matrix(int x=,int y=):n(x),m(y) {memset(a,,sizeof a);}
void init()
{
for(int i=;i<n;i++)a[i][i]=;//0 ~ n-1
}
Matrix operator * (const Matrix &y) const
{
Matrix x(n,y.m);
for(int i=;i<n;i++)//从0到n-1
for(int k=;k<m;k++)
for(int j=;j<y.m;j++)
(x.a[i][j]+=(ll)a[i][k]*y.a[k][j]%mod)%=mod;
return x;
}
};
void getnxt()
{
nxt[]=nxt[]=;//第0位有字符,但含义是无匹配
for(int i=;i<m;i++)
{
// int k=i;
int k=nxt[i];
while(s[i]!=s[k]&&k)k=nxt[k];
nxt[i+]=(s[i]==s[k])?k+:;//前一位的nxt冒进一位,对应下面从0开始的字符串匹配
}
}
Matrix pw(Matrix x,int k)
{
Matrix ret(x.n,x.m); ret.init();
for(;k;k>>=,x=x*x)
if(k&)ret=ret*x;
return ret;
}
int main()
{
scanf("%d%d%d%s",&n,&m,&mod,&s);
getnxt();
Matrix f(m,m);
for(int i=;i<m;i++)
for(int j='';j<='';j++)//第i位上填j
{
int k=i;//已经有长度为i的前缀,而k对应字符串上i的后一位
while(k&&s[k]!=j)k=nxt[k];//冒进一位的nxt,表示给i后一位进行匹配
if(s[k]==j)k++;//匹配到了第k位,也就是有了k+1长度的前缀
if(k!=m)f.a[i][k]++;
}
Matrix fn=pw(f,n);
Matrix ans(,m);
ans.a[][]=; ans=ans*fn;
for(int i=;i<m;i++)
(sum+=ans.a[][i])%=mod;
printf("%d",sum);
return ;
}

bzoj1009 [HNOI2008]GT考试——KMP+矩阵快速幂优化DP的更多相关文章

  1. [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)

    Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...

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

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

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

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

  4. BZOJ 1009 [HNOI2008]GT考试 (KMP + 矩阵快速幂)

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

  5. 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 ...

  6. 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个 ...

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

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

  8. [HNOI2008][bzoj1009] GT考试 [KMP+矩阵快速幂]

    题面 传送门 思路 首先,如果$n$和$m$没有那么大的话,有一个非常显然的dp做法: 设$dp[i][j]$表示长度为i的字符串,最后j个可以匹配模板串前j位的情况数 那么显然,答案就是$\sum_ ...

  9. BZOJ 1009 [HNOI2008]GT考试(矩阵快速幂优化DP+KMP)

    题意: 求长度为n的不含长为m的指定子串的字符串的个数 1s, n<=1e9, m<=50 思路: 长见识了.. 设那个指定子串为s f[i][j]表示长度为i的字符串(其中后j个字符与s ...

随机推荐

  1. 模板—treap

    #include<iostream> #include<cstdio> #include<cstdlib> #define INF 0x7fffffff using ...

  2. Springboot2.0中jpa默认创建的mysql表为myisam引擎问题

    使用Springboot2.0后,使用jpa操作mysql数据库时,默认创建的表的引擎是myisam,myisam是不能加外键的,找了一些资源,最终可以用此方法解决! yml格式: spring: j ...

  3. linux 安装 phpstorm 并破解

    下载官方软件linux版phpstrom, 貌似很卡要FQ. 我下载我的百度网盘备用了.解压目录, mv 到/opt/ 下 cd进  bin目录下chmod  777 phpstorm.sh执行 ./ ...

  4. on绑定事件支持的事件类型

    blurfocusfocusinfocusoutloadresizescrollunloadclickdblclickmousedownmouseupmousemovemouseovermouseou ...

  5. vue-router2.0二级路由的简单使用

    1.app.vue中 <template> <div id="app"> <router-view></router-view> & ...

  6. Tree(树的还原以及树的dfs遍历)

    紫书:P155 uva  548   You are to determine the value of the leaf node in a given binary tree that is th ...

  7. i2c中start和restart的区别

    有的硬件芯片提供了一个个寄存器,供我们很好的操作i2c,但是,在用的时候,我们是不知道他到地是怎么操作的,下边,我就探讨下i2c中的start和restart的区别. start是在scl是高电平的时 ...

  8. hdu 2647拓扑排序 结构体模拟容器

    #include<stdio.h> #include<queue> #include<iostream> using namespace std; #define ...

  9. ssh整合配置文件------web.xml配置

    <?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://w ...

  10. R - Milking Time DP

    Bessie is such a hard-working cow. In fact, she is so focused on maximizing her productivity that sh ...