---恢复内容开始---

题目大意:给定一个由数字构成的字符串A(len<=20),让你选择一个长度为n(n是给定的)字符串X,一个合法的字符串X被定义为,字符串X中不存在任何一段子串与A完全相同,求互不相同的合法的字符串L的数量

第一眼看就没啥思路....瞅了一眼题解,是KMP优化DP,然后再用矩阵优化DP

思路还是不难的,首先用KMP求出原字符串的next数组,再用next转移

定义f[i][j]是当前X串匹配到了第i位,已经匹配到了字符串A的第j位

每次在X串的第j+1位填上一个数c,那么X串现在最长能匹配上A串的位置

就是从第j+1位一直往前跳next,直到碰到一个位置a[k]==a[j]或k==0也匹配不到

 int k=i+;
for(k=i+;k>&&a[k]!=c;k=nxt[k])
;
pw.mp[k][i]++;

这是一个连续的过程,上面是构建矩阵的核心代码(原来的代码太丑了我改了一下)

至于为什么要这么跳呢,这是一个类似于"贪心"的过程,但并不是我们主动去贪心

因为我们要保证每次转移的位置都是正确的

然后发现N<=1e9有点大,矩阵乘法优化一下即可

 #include <map>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
#define N 23
#define ui unsigned int
#define inf 0x3f3f3f3f
using namespace std;
//re
int n,len;
ui mod;
char str[N];
int a[N],nxt[N];
struct mtx{
ui mp[N][N];
friend mtx operator *(const mtx &s1,const mtx &s2)
{
mtx ret;memset(&ret,,sizeof(ret));
for(int i=;i<len;i++)
for(int j=;j<len;j++)
for(int k=;k<len;k++)
(ret.mp[i][j]+=(s1.mp[i][k]*s2.mp[k][j])%mod)%=mod;
return ret;
}
mtx qpow(mtx &ans,mtx &x,int y)
{
while(y){
if(y&) ans=x*ans;
x=x*x;y>>=;
}
}
}M;
void get_kmp()
{
int i=,j=;
nxt[]=;
while(i<=len)
if(j==||a[i]==a[j])
i++,j++,nxt[i]=j;
else j=nxt[j];
} int main()
{
scanf("%d%d%u",&n,&len,&mod);
scanf("%s",str+);
for(int i=;i<=len;i++) a[i]=str[i]-'';
get_kmp();
mtx pw;memset(&pw,,sizeof(pw));
for(int i=;i<len;i++)
for(int c=;c<=;c++)
{
if(i==len-&&a[len]==c) continue;
int k=i+;
for(k=i+;k>&&a[k]!=c;k=nxt[k]);
pw.mp[k][i]++;
}
mtx ret;memset(&ret,,sizeof(ret));
ret.mp[][]=;
M.qpow(ret,pw,n);
ui ans=;
for(int i=;i<len;i++)
(ans+=ret.mp[i][])%=mod;
printf("%u\n",ans);
return ;
}

---恢复内容结束---

BZOJ 1009 [HNOI2008]GT考试 (KMP+矩阵乘法)的更多相关文章

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

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

  2. bzoj 1009: [HNOI2008]GT考试 -- KMP+矩阵

    1009: [HNOI2008]GT考试 Time Limit: 1 Sec  Memory Limit: 162 MB Description 阿申准备报名参加GT考试,准考证号为N位数X1X2.. ...

  3. 题解:BZOJ 1009 HNOI2008 GT考试 KMP + 矩阵

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

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

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

  5. BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )

    写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...

  6. BZOJ 1009 HNOI2008 GT考试 KMP算法+矩阵乘法

    标题效果:给定的长度m数字字符串s.求不包括子s长度n数字串的数目 n<=10^9 看这个O(n)它与 我们不认为这 令f[i][j]长度i号码的最后的字符串j位和s前者j数字匹配方案 例如,当 ...

  7. [bzoj1009][HNOI2008]GT考试——KMP+矩阵乘法

    Brief Description 给定一个长度为m的禁止字符串,求出长度为n的字符串的个数,满足: 这个字符串的任何一个字串都不等于给定字符串. 本题是POJ3691的弱化版本. Algorithm ...

  8. BZOJ1009: [HNOI2008]GT考试(KMP+矩阵乘法)

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

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

    题目链接 设f[i][j]为当前是第i位考号.现在匹配到第j位(已有j-1位和A[]匹配)的方案数 因为假如当前匹配j位,如果选择的下一位与A[j+1]不同,那么新的匹配位数是fail[j]而不是0, ...

随机推荐

  1. 【JavaScript框架封装】公共框架的封装

    /* * @Author: 我爱科技论坛 * @Time: 20180706 * @Desc: 实现一个类似于JQuery功能的框架 // 公共框架 // 种子模块:命名空间.对象扩展.数组化.类型的 ...

  2. 封装自己的jquery框架

    jQuery is a fast small JavaScript library 如何封装自己的jQuery <script> // 这里使用沙箱模式,可以防止全局污染 (functio ...

  3. Project Euler 2 Even Fibonacci numbers

    题意:斐波那契数列中的每一项都是前两项的和.由1和2开始生成的斐波那契数列前10项为:1, 2, 3, 5, 8, 13, 21, 34, 55, 89, -考虑该斐波那契数列中不超过四百万的项,求其 ...

  4. Project Euler 8 Largest product in a series

    题意:寻找这 1000 个数中相邻 13 个数相乘积最大的值 思路:首先想到的是暴力,但是还可以利用之前记录过的数值,什么意思呢?即在计算 2 - 14 后,再计算 3 - 15 时完全可以利用之前计 ...

  5. DNS解析流程原理(图例)

    13台根服务器的dns: 1.root-servers.net198.41.0.4美国2.root-servers.net192.228.79.201美国(另支持IPv6)3.root-servers ...

  6. js生产随机数

    var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz"; var string_le ...

  7. JavaScript基础简介

    JavaScript引入的方式 直接在<script>标签中写 <script> console.log('hello world!'); </script> 引入 ...

  8. JAVA循环迭代中删除或添加集合数据报java.util.ConcurrentModificationException错误

    1.写出下面的输出结果 public class test{ public static void main(String [] args) List<String> list = new ...

  9. 在MVC中使用泛型仓储模式和依赖注入实现增删查改

    标签: 原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository ...

  10. 从零開始写游戏引擎(一) - project创建以及文件夹设置还有版本号控制

    一句话提要 好的開始等于成功了一半. 创建文件夹结构 project文件夹下最好分为以下几个文件夹 Docs - 开发文档,设计文档 Assets - 角色,动作,模型和音效等 Source - 代码 ...