[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)

题面

阿申准备报名参加GT考试,准考证号为N位数X1X2….Xn,他不希望准考证号上出现不吉利的数字。他的不吉利数学A1A2…Am有M位,不出现是指X1X2…Xn中没有恰好一段等于A1A2…Am. A1和X1可以为0

\(0 \leq X_i \leq 9,0\leq Ai\leq 9,m \leq 20,n \leq 10^9\)

分析

先考虑暴力的思路,设\(dp[i][j]\)表示前i位数与不吉利数字匹配了前j位的方案数

那么\(dp[i][f(j,c)]=\sum dp[i-1][j] (c \in[0,9])\)

实际上就是从0~9枚举第i位的数字,然后更新匹配的位数。其中\(f(j,c)\)表示加入数字c后的匹配位数。

但是\(n \leq 10^9\),直接dp显然会超时,发现每层转移都是一样的,所以可以矩阵快速幂优化

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000
#define maxm 20
using namespace std;
typedef long long ll;
char t[maxm+5];
int nex[maxm+5];
void get_nex(char *a){
int len=strlen(a+1);
for(int i=2,j=0;i<=len;i++){
while(j>0&&a[j+1]!=a[i]) j=nex[j];
if(a[j+1]==a[i]) j++;
nex[i]=j;
}
} int n,m,mod;
int match(int j,char c){
while(j>0&&t[j+1]!=c) j=nex[j];
if(t[j+1]==c) j++;
return j;
} struct matrix{
ll x[maxn+5][maxn+5];
void set(int p){
if(p==0){
for(int i=0;i<m;i++) for(int j=0;j<m;j++) x[i][j]=0;
}else{
for(int i=0;i<m;i++) for(int j=0;j<m;j++) x[i][j]=0;
for(int i=0;i<m;i++) x[i][i]=1;
}
}
void print(){
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
printf("%lld ",x[i][j]);
}
printf("\n");
}
}
friend matrix operator * (matrix a,matrix b){
matrix ans;
ans.set(0);
for(int i=0;i<m;i++){
for(int j=0;j<m;j++){
for(int k=0;k<m;k++){
ans.x[i][j]+=a.x[i][k]*b.x[k][j]%mod;
ans.x[i][j]%=mod;
}
}
}
return ans;
}
};
matrix fast_pow(matrix x,int k){
matrix ans;
ans.set(1);
while(k){
if(k&1) ans=ans*x;
x=x*x;
k>>=1;
}
return ans;
} int main(){
scanf("%d %d %d",&n,&m,&mod);
scanf("%s",t+1);
get_nex(t);
// dp[0][0]=1;
// for(int i=1;i<=n;i++){
// for(int j=0;j<m;j++){
// for(char ch='0';ch<='9';ch++){
// int k=match(j,ch);
// dp[i][k]+=dp[i-1][j];
// dp[i][k]%=mod;
// }
// }
// }
matrix tp,ans;
tp.set(0);
for(int j=0;j<m;j++){
for(char ch='0';ch<='9';ch++){
int k=match(j,ch);
tp.x[j][k]++;
}
}
// tp.print();
ans=fast_pow(tp,n);
// ans.print();
ll res=0;
for(int j=0;j<m;j++){
res+=ans.x[0][j];
res%=mod;
}
printf("%lld\n",res);
}

[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)的更多相关文章

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

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

  2. bzoj1009: [HNOI2008]GT考试 ac自动机+矩阵快速幂

    https://www.lydsy.com/JudgeOnline/problem.php?id=1009 阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9 ...

  3. [BZOJ1009] [HNOI2008] GT考试 (KMP & dp & 矩阵乘法)

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

  4. $bzoj1009-HNOI2008$ $GT$考试 字符串$dp$ 矩阵快速幂

    题面描述 阿申准备报名参加\(GT\)考试,准考证号为\(N\)位数\(x_1,x_2,...,x_n\ (0\leq x_i\leq 9)\),他不希望准考证号上出现不吉利的数字. 他的不吉利数字\ ...

  5. 【BZOJ-1009】GT考试 KMP+DP+矩阵乘法+快速幂

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

  6. bzoj 1009: [HNOI2008]GT考试【kmp+dp+矩阵快速幂】

    看n和k的范围长得就很像矩阵乘法了 设f[i][j]表示到第i个位置的后缀最长匹配目标串的j位.转移的话显然是枚举0~9,然后选择f[i+1]中能被他转移的加起来,需要用到next数组.然后构造矩阵的 ...

  7. [BZOJ1009][HNOI2008]GT考试(KMP+DP)

    [不稳定的传送门 Solution dp[i][j]表示前i个字符当前匹配到不吉利串的第j个,即当前方案的后缀等于不吉利串前缀 然而由于n过大,不能直接转移,用矩阵优化 Code #include & ...

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

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

  9. bnuoj 34985 Elegant String DP+矩阵快速幂

    题目链接:http://acm.bnu.edu.cn/bnuoj/problem_show.php?pid=34985 We define a kind of strings as elegant s ...

随机推荐

  1. LOJ #6145. 「2017 山东三轮集训 Day7」Easy 点分树+线段树

    这个就比较简单了~ Code: #include <cstdio> #include <algorithm> #define N 100004 #define inf 1000 ...

  2. Luogu P4707 重返现世 (拓展Min-Max容斥、DP)

    题目链接 https://www.luogu.org/problem/P4707 题解 最近被神仙题八连爆了-- 首先Min-Max容斥肯定都能想到,问题是这题要用一个扩展版的--Kth Min-Ma ...

  3. Unity3D_(物理引擎)Rigidbody组件

    Rigidbody组件刚体(Rigidbody)是Unity物理引擎中的重要组件,一个游戏对象添加了刚体组件以后就开始接受物理力学的影响了,比如重力.空气摩擦力.碰撞产生的推力   Learn 相同高 ...

  4. Confluence备份,数据迁移

    一.Confluence的备份.恢复1)Confluence的备份 管理员账号登录Confluence,点击右上角的"一般配置"-"每日备份管理",如下图(默认 ...

  5. iview简单使用+按需加载组件的方法(全局和局部)

    1,简单使用 vue项目中使用iview非常简单: 首先安装依赖: $ npm install iview --save 会安装最新版本的依赖,安装完成后package.json会出现如下图配置 表示 ...

  6. RedisTemplate集合使用说明-opsForList(二)

    1.leftPush(K key, V value) 在变量左边添加元素值. Java代码   redisTemplate.opsForList().leftPush("list" ...

  7. C++入门经典-例3.8-使用条件表达式判断一个数是否是3和5的整倍数

    1:代码如下: // 3.8.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include<iostream> using ...

  8. IDEA 创建maven jar、war、 pom项目

    创建java jar.pom项目时创建maven-archetype-quickstart 创建java war项目时创建maven-archetype-webapp

  9. shiro 注解不生效

    springboot集成shiro时,使用@RequiresRoles注解不生效. shiro @RequiresRoles底层使用springaop技术: 1.@RequiresRoles修饰ser ...

  10. D3(没写完

    说在博客前 这篇博客有许多使用到 STL 的地方,由于本人实在是记不全,所以我也参考了北大的一些教材,就别说我黈力了 QwQ 数据结构 今天讲的是数据结构啦(也是我这个蒟蒻最喜欢的 一些天天见面的好盆 ...