BZOJ1009 矩阵快速幂+DP+KMP
Problem 1009. -- [HNOI2008]GT考试
1009: [HNOI2008]GT考试
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 3773 Solved: 2314
[Submit][Status][Discuss]
Description
阿申准备报名参加GT考试,准考证号为N位数X1X2....Xn(0<=Xi<=9),他不希望准考证号上出现不吉利的数字。
他的不吉利数学A1A2...Am(0<=Ai<=9)有M位,不出现是指X1X2...Xn中没有恰好一段等于A1A2...Am. A1和X1可以为
0
Input
第一行输入N,M,K.接下来一行输入M位的数。 N<=10^9,M<=20,K<=1000
Output
阿申想知道不出现不吉利数字的号码有多少种,输出模K取余的结果.
Sample Input
111
Sample Output
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m,mod;
int next[],num[];
void get(){
int i=,j=-;
next[]=-;
while(i<m){
if(j==-||num[i]==num[j]) next[++i]=++j;
else j=next[j];
}
}
struct node{
int mx[][];
node(){memset(mx,,sizeof(mx));}
}a;
node mult(const node &a,const node &b){
node c;
for(int i=;i<m;++i)
for(int j=;j<m;++j)
for(int k=;k<m;++k)
c.mx[i][j]=(c.mx[i][j]+a.mx[i][k]*b.mx[k][j])%mod;
return c;
}
node ksm(node a,int k){
node r;
for(int i=;i<m;++i)
r.mx[i][i]=;
while(k){
if(k&) {r=mult(r,a);k|=;}
k>>=;
a=mult(a,a);
}
return r;
}
int main(){
scanf("%d%d%d",&n,&m,&mod);
getchar();
for(int i=;i<m;++i) num[i]=getchar()-'';
get();
for(int i=;i<m;++i) //进行第i个元素填充
for(int j=;j<=;++j){ //若第i个元素为j
int tmp=i; //这里首先假设后缀满足了i个,然后对i个位置(数组元素从0开始,所以比较的时候还是num[tmp]而不是num[tmp+1])填充j
while(tmp!=-&&j!=num[tmp]) tmp=next[tmp]; //若是不相同,就向前找。
if(tmp==-) ++a.mx[i][]; //如果未找到匹配的位置,则dp[i+1][0]的系数a[i][0]要加1
else ++a.mx[i][tmp+]; //可以转移到tmp+1的位置(若开始就匹配,就表示可以转移到他的下一个位置,系数加1)
}//系数矩阵显然是个方阵,第i行第j列表示前一个后缀满足i个转移到后一个后缀满足j个的系数(从而也可以知道系数矩阵第一行起初就是dp[1][0],dp[1][1]...dp[1][m])
a=ksm(a,n);
int ans=;
for(int i=;i<m;++i)
ans=(ans+a.mx[][i])%mod;
printf("%d\n",ans);
}
BZOJ1009 矩阵快速幂+DP+KMP的更多相关文章
- codeforces 691E 矩阵快速幂+dp
传送门:https://codeforces.com/contest/691/problem/E 题意:给定长度为n的序列,从序列中选择k个数(可以重复选择),使得得到的排列满足xi与xi+1异或的二 ...
- P1357 花园 (矩阵快速幂+ DP)
题意:一个只含字母C和P的环形串 求长度为n且每m个连续字符不含有超过k个C的方案数 m <= 5 n <= 1e15 题解:用一个m位二进制表示状态 转移很好想 但是这个题是用矩阵快速 ...
- Codeforces 576D Flights for Regular Customers 矩阵快速幂+DP
题意: 给一个$n$点$m$边的连通图 每个边有一个权值$d$ 当且仅当当前走过的步数$\ge d$时 才可以走这条边 问从节点$1$到节点$n$的最短路 好神的一道题 直接写做法喽 首先我们对边按$ ...
- COJ 1208 矩阵快速幂DP
题目大意: f(i) 是一个斐波那契数列 , 求sum(f(i)^k)的总和 由于n极大,所以考虑矩阵快速幂加速 我们要求解最后的sum[n] 首先我们需要思考 sum[n] = sum[n-1] + ...
- Codeforces 954 dijsktra 离散化矩阵快速幂DP 前缀和二分check
A B C D 给你一个联通图 给定S,T 要求你加一条边使得ST的最短距离不会减少 问你有多少种方法 因为N<=1000 所以N^2枚举边数 迪杰斯特拉两次 求出Sdis 和 Tdis 如果d ...
- BZOJ1009: [HNOI2008]GT考试 (矩阵快速幂 + DP)
题意:求一个长度为n的数字字符串 (n <= 1e9) 不出现子串s的方案数 题解:用f i,j表示长度为i匹配到在子串j的答案 用kmp的失配函数预处理一下 然后这个转移每一个都是一样的 所以 ...
- Codeforces 989E A Trance of Nightfall 矩阵快速幂+DP
题意:二维平面上右一点集$S$,共$n$个元素,开始位于平面上任意点$P$,$P$不一定属于$S$,每次操作为选一条至少包含$S$中两个元素和当前位置$P$的直线,每条直线选取概率相同,同一直线上每个 ...
- bzoj2004 矩阵快速幂优化状压dp
https://www.lydsy.com/JudgeOnline/problem.php?id=2004 以前只会状压dp和矩阵快速幂dp,没想到一道题还能组合起来一起用,算法竞赛真是奥妙重重 小Z ...
- [BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂)
[BZOJ1009] [HNOI2008] GT考试(KMP+dp+矩阵快速幂) 题面 阿申准备报名参加GT考试,准考证号为N位数X1X2-.Xn,他不希望准考证号上出现不吉利的数字.他的不吉利数学A ...
随机推荐
- Libra白皮书解读
文章目录 Libra简介 Libra区块链 Libra货币和存储 Libra协会 Libra简介 Libra是facebook发起的一个区块链项目,其使命是建立一套简单的.无国界的货币和为数十亿人服务 ...
- JDK11的重要新特性
文章目录 JDK11发布啦 Oracle不再提供JRE和Server JRE下载 删除部署工具 JavaFX不再包含在JDK中 删除Java EE和CORBA模块 JDK11发布啦 JDK11 在20 ...
- Scala教程之:面向对象的scala
文章目录 面向对象的scala Unified Types Classes Traits 面向对象的scala 我们知道Scala是一种JVM语言,可以合java无缝衔接,这也就大大的扩展了scala ...
- Linux指令面试题01-进程查看与终止
查看某一进程是否运行:ps -ef|grep 程序名 终止程序: kill pid 转载于:https://www.cnblogs.com/feihujiushiwo/p/10896636.html
- Git 提交项目命令
git add . //添加⽂件到待提交区 git commit -m "注释" //创建⼀个提交 git push origin //将修改内容提交
- 基于LINUX 主机防火墙的端口转发
由于centos7之后将默认防火墙从原来的iptables更改为firewall.本文主要记录基于firewall的端口转发部署. 1.检查防火墙状态 systemctl status fir ...
- MATLAB学习1 之画图函数
ezplot适用条件 "ezplot"命令可以用于显函数.隐函数和参数方程作图. 不同函数的使用格式 显函数y=f(x),ezplot函数的调用格式为ezplot(f, [xmin ...
- 获得CCNA和CCNP及CCIE认证的必备条件和有效期绍
CCNA认证培训介绍 CCNA认证(CCNA-思科网络安装和支持认证助理)是整个Cisco认证体系中最初级的认证,同时它也是获得CCNP认证.CCDP认证和CCSP认证的必要条件(CCIP认证.CCI ...
- winform练习-通过遍历Control容器中的对象统一委托事件-楼盘选择器
1.窗体布局如下,一个label标签内容如下,一个btnSave按钮,用于保存,其他九个按钮用于选择楼盘. 2. 按钮存于Control容器中,编写方法遍历容器中的button,通过条件过滤掉不是bu ...
- 算法竞赛进阶指南--在单调递增序列a中查找>=x的数中最小的一个(即x或x的后继)
while (l < r) { int mid = (l + r) / 2; if (a[mid] >= x) r = mid; else l = mid + 1; }