【bzoj1009】: [HNOI2008]GT考试 字符串-kmp-矩阵乘法-DP
先用kmp写个暴力
/* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
char s[];
int n,m,p,fail[],f[][]; void kmp(){
fail[]=;
for (int i=;i<=m;i++){
fail[i]=fail[i-];
if (s[fail[i-]]==s[i-]) fail[i-]=fail[fail[i-]];
while (s[fail[i]]!=s[i-] && fail[i]) fail[i]=fail[fail[i]];
fail[i]++;
}
} int main(){
scanf("%d%d%d",&n,&m,&p);
scanf("%s",s+);
kmp();
f[][]=;
for (int i=;i<=n;i++){
for (int j=;j<m;j++){
for (int k='',now=j+;k<='';k++,now=j+){
while (k!=s[now] && now) now=fail[now];
f[i][now]=(f[i][now]+f[i-][j])%p;
}
}
}
int ans=;
for (int i=;i<m;i++){
ans=(ans+f[n][i])%p;
}
printf("%d\n",ans);
return ;
}
暴力
然后对着转移方程yy一下矩阵就好辣
/* http://www.cnblogs.com/karl07/ */
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
char s[];
int n,m,p,fail[];
struct MAT{
int m[][];
int x,y;
}m1,m2; MAT operator * (const MAT &a,const MAT &b){
MAT c;
c.x=b.x,c.y=a.y;
for (int i=;i<=c.x;i++){
for (int j=;j<=c.y;j++){
c.m[i][j]=;
for (int k=;k<=b.y;k++){
c.m[i][j]=(c.m[i][j]+a.m[k][j]*b.m[i][k])%p;
}
}
}
return c;
} int sum(MAT a){
int ans=;
for (int i=;i<=a.x;i++){
for (int j=;j<=a.y;j++){
ans=(ans+a.m[i][j])%p;
}
}
return ans;
} void kmp(){
fail[]=;
for (int i=;i<=m;i++){
fail[i]=fail[i-];
if (s[fail[i-]]==s[i-]) fail[i-]=fail[fail[i-]];
while (s[fail[i]]!=s[i-] && fail[i]) fail[i]=fail[fail[i]];
fail[i]++;
}
} MAT qpow(int x){
for (;x;x=(x>>),m2=m2*m2) if (x&) m1=m1*m2;
return m1;
} int main(){
scanf("%d%d%d",&n,&m,&p);
scanf("%s",s+);
kmp();
m1.x=m;m1.y=;m1.m[][]=;
m2.x=m2.y=m;
for (int i=;i<=m;i++) m1.m[i][]=;
for (int i=;i<=m;i++) for (int j=;j<=m;j++) m2.m[i][j]=;
for (int j=;j<m;j++){
for (int k='',now=j+;k<='';k++,now=j+){
while (k!=s[now] && now)now=fail[now];
m2.m[now+][j+]++;
}
}
printf("%d\n",sum(qpow(n)));
return ;
}
正解
为什么感觉自己的kmp写的好奇怪。。
【bzoj1009】: [HNOI2008]GT考试 字符串-kmp-矩阵乘法-DP的更多相关文章
- bzoj1009: [HNOI2008]GT考试(kmp+矩阵乘法)
1009: [HNOI2008]GT考试 题目:传送门 题解: 看这第一眼是不是瞬间想起组合数学??? 没错...这样想你就GG了! 其实这是一道稍有隐藏的矩阵乘法,好题! 首先我们可以简化一下题意: ...
- HNOI2008 GT考试 (KMP + 矩阵乘法)
传送门 这道题目的题意描述,通俗一点说就是这样:有一个长度为n的数字串(其中每一位都可以是0到9之间任意一个数字),给定一个长度为m的模式串,求有多少种情况,使得此模式串不为数字串的任意一个子串.结果 ...
- P3193 [HNOI2008]GT考试(KMP+矩阵乘法加速dp)
P3193 [HNOI2008]GT考试 思路: 设\(dp(i,j)\)为\(N\)位数从高到低第\(i\)位时,不吉利数字在第\(j\)位时的情况总数,那么转移方程就为: \[dp(i,j)=dp ...
- 2018.10.22 bzoj1009: [HNOI2008]GT考试(kmp+矩阵快速幂优化dp)
传送门 f[i][j]f[i][j]f[i][j]表示从状态"匹配了前i位"转移到"匹配了前j位"的方案数. 这个东西单次是可以通过跳kmp的fail数组得到的 ...
- 【BZOJ1009】[HNOI2008]GT考试 next数组+矩阵乘法
[BZOJ1009][HNOI2008]GT考试 Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的 ...
- [Bzoj1009][HNOI2008]GT考试(KMP)(矩乘优化DP)
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4309 Solved: 2640[Submit][Statu ...
- bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂
https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9 ...
- BZOJ1009:[HNOI2008]GT考试(AC自动机,矩乘DP)
Description 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字. 他的不吉利数学A1A2...Am(0< ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
随机推荐
- md5加密小程序
#-*- coding:utf-8 -*- __author__ = "MuT6 Sch01aR" import hashlib m = hashlib.md5() m.updat ...
- Deep Learning 学习笔记(7):神经网络的求解 与 反向传播算法(Back Propagation)
反向传播算法(Back Propagation): 引言: 在逻辑回归中,我们使用梯度下降法求参数方程的最优解. 这种方法在神经网络中并不能直接使用, 因为神经网络有多层参数(最少两层),(?为何不能 ...
- C#读写EXCEL(二) ZedGraph在Asp.net中的应用
C#读写EXCEL(二) 2010-08-25 14:50:42| 分类: 默认分类 | 标签: |举报 |字号大中小 订阅 用微信 “扫一扫” 将文章分享到朋友圈. 用易信 “扫一扫” ...
- leetcode867
vector<vector<int>> transpose(vector<vector<int>>& A) { vector<vector ...
- fgets、gets和scanf的区别
gets()从stdin流中读取字符串,直至接受到换行符或EOF时停止,并将读取的结果存放在buffer指针所指向的字符数组中.换行符不作为读取串的内容,读取的换行符被转换为null值,并由此来结束字 ...
- mysql如何进行以=分割的字符串的拆分
SUBSTRING_INDEX(str, delim, count) str: 要处理的字符串 delim: 分割符 count: 计数 如果为正数,则从左开始数,如果为负数,则从右开始数 使用示例: ...
- pl/sql简介
- easylogging++学习记录(二):流式日志
easylogging++日志库流式日志的写入,依赖于el::base::Writer类的析构,以debug日志为例:具体代码如下: #define LOG(LEVEL) CLOG(LEVEL, EL ...
- linux SIGSEGV 信号捕捉,保证发生段错误后程序不崩溃
在Linux中编程的时候 有时候 try catch 可能满足不了我们的需求.因为碰到类似数组越界 ,非法内存访问之类的 ,这样的错误无法捕获.下面我们介绍一种使用捕获信号实现的异常 用来保证诸如段错 ...
- c++多线程编程(二)
这是道面试题目:有三个线程分别打印A.B.C,请用多线程编程实现,在屏幕上循环打印10次ABCABC… 见代码: #include <iostream> #include <Wind ...