洛谷P3193 [HNOI2008]GT考试(KMP,矩阵)
大佬讲的真吼->这里
首先考虑dp,设$f[i][j]$表示长串匹配到第$i$位,短串最多匹配到$j$位时的方案数
那么答案就是$\sum_{i=0}^{m-1}f[n][i]$
然后考虑一下dp的转移,一种是加进的新字符$i+1$与$j+1$匹配,那么$dp[i][j]$可以直接转移到$dp[i+1][j+1]$
然后如果不匹配怎么办?这种时候,有可能新串的一个后缀和短串的一个前缀有了匹配
对于这一点,我们就是要知道,对于一个匹配到长度为$j$的串,转移到$k$的串的方案,也就对于长度为$i$的串,加一个数字,能加入多少种数字,使得长度为$j$的匹配变成长度为$k$的匹配
然后这个可以用kmp计算
然后看一下dp式子$f[i][j]=\sum{k=0}^{m-1}f[i-1][k]*g[k][j]$
那这就是一个矩阵乘法了……因为$g[i][j]$是固定不变的,所以把$f[i][j]$看做一个矩阵
那么$F[i]=F[i-1]*G$
那么矩阵快速幂一下就行了
//minamoto
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=;
int f[N][],n,m,mod;
int kmp[N],match[N][];char s[N];
inline void init(){
kmp[]=-;
for(int i=;i<=m;++i){
int j=kmp[i-];
while((~j)&&s[j+]!=s[i]) j=kmp[j];
kmp[i]=j+;
}
kmp[]=;
for(int i=;i<m;++i)
for(int j='';j<='';++j){
int tmp=i;
while(s[tmp+]!=j&&tmp) tmp=kmp[tmp];
if(s[tmp+]==j) ++tmp;
if(tmp<m) ++match[i][tmp];
}
}
struct Matrix{
int g[][];
Matrix(){memset(g,,sizeof(g));}
Matrix operator *(Matrix B){
Matrix res;
for(int i=;i<m;++i)
for(int j=;j<m;++j)
for(int k=;k<m;++k)
(res.g[i][j]+=g[i][k]*B.g[k][j])%=mod;
return res;
}
}F,G;
inline Matrix ksm(Matrix A,int k){
Matrix res;
for(int i=;i<=m;++i) res.g[i][i]=;
while(k){
if(k&) res=res*A;
A=A*A,k>>=;
}
return res;
}
int main(){
// freopen("testdata.in","r",stdin);
scanf("%d%d%d%s",&n,&m,&mod,s+);
init();
F.g[][]=;
for(int i=;i<=m;++i)
for(int j=;j<=m;++j)
G.g[i][j]=match[i][j];
G=ksm(G,n);
F=F*G;
int ans=;
for(int i=;i<m;++i) (ans+=F.g[][i])%=mod;
printf("%d\n",ans);
return ;
}
洛谷P3193 [HNOI2008]GT考试(KMP,矩阵)的更多相关文章
- 洛谷P3193 [HNOI2008]GT考试 kmp+dp
正解:kmp+dp+矩阵优化 解题报告: 传送门! 啊刚说想做矩阵优化dp的字符串题就找到辣QwQ虽然不是AC自动机的但都差不多嘛QwQ 首先显然可以想到一个dp式?就f[i][j]:凑出i位了,在s ...
- 洛谷P3193 [HNOI2008]GT考试(dp 矩阵乘法)
题意 题目链接 Sol 设\(f[i][j]\)表示枚举到位置串的第i位,当前与未知串的第j位匹配,那么我们只要保证在转移的时候永远不会匹配即可 预处理出已知串的每个位置加上某个字符后能转移到的位置, ...
- 【KMP】【矩阵加速】【递推】洛谷 P3193 [HNOI2008]GT考试 题解
看出来矩阵加速也没看出来KMP…… 题目描述 阿申准备报名参加 GT 考试,准考证号为\(N\)位数\(X_1,X_2…X_n(0\le X_i\le9)\),他不希望准考证号上出现不吉利的数 ...
- BZOJ 1009 [HNOI2008]GT考试 (KMP + 矩阵快速幂)
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4266 Solved: 2616[Submit][Statu ...
- bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...
- [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)
Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...
- 题解:BZOJ 1009 HNOI2008 GT考试 KMP + 矩阵
原题描述: 阿申准备报名参加GT考试,准考证号为N位数 X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学A1A2...Am(0<=Ai&a ...
- [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法
Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...
- bzoj 1009 [HNOI2008]GT考试——kmp+矩阵优化dp
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 首先想到 确保模式串不出现 就是 确保每个位置的后缀不是该模式串. 为了dp,需要记录 ...
随机推荐
- windows下安装配置nginx
下载nginx-1.0.11.zip, 解压到到nginx目录下 D:\nginx\conf 修改conf下的nginx.conf文件, 默认是80端口,若该端口被占则可以修改 listen 8073 ...
- django-pagination分页
1. 将该APP安装至Django项目中.(settings.py) INSTALLED_APPS = ( # ... 'pagination', ) 2. 在Django项目的middleware中 ...
- Android: 利用SurfaceView绘制股票滑动直线解决延迟问题
1.背景介绍 最近项目要绘制股票走势图,并绘制能够跟随手指滑动的指示线(Indicator)来精确查看股票价格和日期.如下图所示: 上图中的那条白色直线就是股票的指示线,用来跟随手指精确确定股票的时间 ...
- Agc011_F Train Service Planning
先放题面,再放LHX巨佬题解 接着就是%%%.$orz.Oro.Or2.Otz.OTL.sto.rzo.Jto$.On_.○| ̄|_啊 模拟赛里直接把这道题刚掉了 一题升天·爆踩全场 这题思维跨越度已 ...
- 使用Visual Studio进行单元测试-Part3
本文主要介绍Visual Studio(2012+)单元测试框架的一些技巧: 测试覆盖率的统计 测试分组 测试Setup/TearDown 测试调试 Exception测试 代码覆盖率的统计 VS下面 ...
- ViewModel中C# Property自动添加OnPropertyChanged处理的小工具, 以及相应Python知识点
在做WPFMVVM中经常会遇到一些Model.ViewModel的属性添加添加私有字段和更改通知方法来支持Binding. 比如把: public class Test { public s ...
- strcmp strcpy的使用 char类型
//判断从控制台输入的密码是否正确 BOOL varifyPassWord(char passWord[] , int index) { BOOL result = YES; int count = ...
- nginx实现带参数目录域名重定向二级域名方法
本文章介绍了关于nginx实现带参数目录域名重定向二级域名方法,有需要学习的朋友可参考一下. 下面的代码是基于nginx的子目录301到其他域名(URL)的规则.作用是例如访问http://www.p ...
- TS学习之枚举
使用枚举可以定义一些有名字的数字常量 enum Test{ one = 1, two, three, four } console.log(Test); /*{ '1': 'one', '2': 't ...
- WPF Invoke与BeginInvoke的区别
Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托. Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句 ...