[HNOI2008][bzoj1009] GT考试 [KMP+矩阵快速幂]
题面
思路
首先,如果$n$和$m$没有那么大的话,有一个非常显然的dp做法:
设$dp[i][j]$表示长度为i的字符串,最后j个可以匹配模板串前j位的情况数
那么显然,答案就是$\sum_{i=0}^{m-1}dp[n][i]$了
转移过程则需要用一个辅助数组:令$g[i][j]$表示模板串的前缀$i$可以转移到前缀$j$的方法数(注意它可能可以转移到很多个串)
辅助数组的生成可以用next数组来推(模板串太短,其实暴力也是可以的)
那么$dp[i+1][k]=dp[i][j]*g[j][k]\left(j=1...m\right)$
然后再看这题的数据范围:$n\leq 10^9$
Easy,加一个矩阵快速幂来解决上面的递推就行了
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
#define inf 1e9
using namespace std;
int MOD;
struct ma{//矩阵类
int n,m,a[25][25];
ma(){n=m=0;memset(a,0,sizeof(a));}
void clear(){n=m=0;memset(a,0,sizeof(a));}
}A,B;
void mul(ma &a,ma b){//矩阵乘法
ma re;int i,j,k;re.n=a.n;re.m=b.m;
for(i=0;i<=re.n;i++){
for(k=0;k<=a.m;k++){
if(!a.a[i][k]) continue;
for(j=0;j<=re.m;j++){
re.a[i][j]=(re.a[i][j]+a.a[i][k]*b.a[k][j]%MOD)%MOD;
}
}
}
a=re;
}
int n,m,a[30],fail[30],f[30][10];char s[30];
void qpow(ma &x,ma &y,int t){//快速幂
while(t){
if(t&1) mul(x,y);
mul(y,y);t>>=1;
}
}
int main(){
scanf("%d%d%d",&m,&n,&MOD);
scanf("%s",s);int i,j,k;
for(i=0;i<n;i++) a[i]=s[i]-'0';a[n]=inf;
fail[0]=fail[1]=0;j=0;
for(i=1;i<n;i++){//求出next数组
while(j&&(a[i]!=a[j])) j=fail[j];
j+=(a[i]==a[j]);fail[i+1]=j;
}
for(i=0;i<n;i++){//生成转移矩阵
for(j=0;j<10;j++){
k=i;while(k&&a[k]!=j) k=fail[k];
k+=(a[k]==j);
if(k<n) B.a[i][k]+=1;
}
}
B.m=B.n=A.m=n-1;A.n=0;A.a[0][0]=1;
qpow(A,B,m);
int ans=0;
for(i=0;i<n;i++) ans+=A.a[0][i],ans%=MOD;
printf("%d",ans);
}
[HNOI2008][bzoj1009] GT考试 [KMP+矩阵快速幂]的更多相关文章
- [bzoj1009](HNOI2008)GT考试 (kmp+矩阵快速幂加速递推)
Description 阿 申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字.他的不吉利数学 A1A2...Am(0&l ...
- bzoj1009 [HNOI2008]GT考试——KMP+矩阵快速幂优化DP
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 字符串计数DP问题啊...连题解都看了好多好久才明白,别提自己想出来的蒟蒻我... 首 ...
- BZOJ 1009 [HNOI2008]GT考试 (KMP + 矩阵快速幂)
1009: [HNOI2008]GT考试 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 4266 Solved: 2616[Submit][Statu ...
- 2018.10.22 bzoj1009: [HNOI2008]GT考试(kmp+矩阵快速幂优化dp)
传送门 f[i][j]f[i][j]f[i][j]表示从状态"匹配了前i位"转移到"匹配了前j位"的方案数. 这个东西单次是可以通过跳kmp的fail数组得到的 ...
- BZOJ 1009: [HNOI2008]GT考试( dp + 矩阵快速幂 + kmp )
写了一个早上...就因为把长度为m的也算进去了... dp(i, j)表示准考证号前i个字符匹配了不吉利数字前j个的方案数. kmp预处理, 然后对于j进行枚举, 对数字0~9也枚举算出f(i, j) ...
- [HNOI2008] GT考试(DP+矩阵快速幂+KMP)
题目链接:https://www.luogu.org/problemnew/show/P3193#sub 题目描述 阿申准备报名参加 GT 考试,准考证号为 N 位数 X1,X2…Xn(0 <= ...
- bzoj1009 GT考试 (kmp+矩阵优化dp)
设f[i][j]是到第i位 已经匹配上了j位的状态数 然后通过枚举下一位放0~9,可以用kmp处理出一个转移的矩阵 然后就可以矩阵快速幂了 #include<bits/stdc++.h> ...
- LightOJ 1268 Unlucky Strings (KMP+矩阵快速幂)
题意:给出一个字符集和一个字符串和正整数n,问由给定字符集组成的所有长度为n的串中不以给定字符串为连续子串的有多少个? 析:n 实在是太大了,如果小的话,就可以用动态规划做了,所以只能用矩阵快速幂来做 ...
- 【bzoj1009】[HNOI2008]GT考试(矩阵快速幂优化dp+kmp)
题目传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=1009 这道题一看数据范围:$ n<=10^9 $,显然不是数学题就是矩乘快速幂优 ...
随机推荐
- python实现剑指offer删除链表中重复的节点
题目描述 在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针. 例如,链表1->2->3->3->4->4->5 处理后 ...
- vue中v-show和v-if的异同
一.官方解释: v-if 是“真正”的条件渲染,因为它会确保在切换过程中条件块内的事件监听器和子组件适当地被销毁和重建. v-if 也是惰性的:如果在初始渲染时条件为假,则什么也不做——直到条件第一次 ...
- 函数定义和调用 -------JavaScript
本文摘要:http://www.liaoxuefeng.com/ 定义函数 在JavaScript中,定义函数的方式如下: function abs(x) { if (x >= 0) { ret ...
- Bootstrap历练实例:按钮(Button)插件单个切换
单个切换 如需激活单个按钮的切换(即改变按钮的正常状态为按压状态,反之亦然),只需向 button 元素添加 data-toggle="button" 作为其属性即可,如下面实例所 ...
- C#进阶之全面解析Lambda表达式
引言 在实际的项目中遇到一个问题,我们经常在网上搜索复制粘贴,其中有些代码看着非常的简洁,比如Lambda表达式,但是一直没有去深入了解它的由来,以及具体的使用方法,所以在使用的时候比较模糊,其次,编 ...
- 0.5px的边框
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Oracle 配置文件目录
Oracle 配置文件目录 ① 在oracle安装目录下,找D:\oracle\product\10.2.0\client_1\NETWORK\ADMIN中的tnsnames.ora文件,找到之后,配 ...
- 1043: [HAOI2008]下落的圆盘
Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1725 Solved: 743[Submit][Status][Discuss] Descripti ...
- 算法竞赛入门经典5.1 从c到c++
这个章节主要是讲述了一些c++的特性,在这里面,对我用处最大的应该就是字符串吧.首先是getline,getchar,stringstream的使用了吧. 首先介绍这三个函数. 1. getline函 ...
- 洛谷 P1346 电车
这道题的关键在建图 把每一个车站看成一个点,将这个车站相连的第一个车站建立一条边权为0的边,对于它所相连的其他车站,建立边权为1的边: 这样我们可以得到一张图: 起点,终点都知道了,跑一边最短路即可 ...