Description

你有一个长度为n的数字串。定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导0),将他们加起来,求f,并求和。比如g(123)=f(1+2+3)+f(1+23)+f(12+3)+f(123)。已知字符串和m后求答案对998244353(7×17×223+1,一个质数)取模后的值。

Input

第一行输入一个字符串,第二行输入m

Output

仅输出一个数表示答案

Sample Input

123
3

Sample Output

394608467

HINT

对于100%的数据,字符串长度不超过500,m<=5

正解:$dp$+矩阵乘法。

矩阵可以用来$dp$转移。。

设$g[i]$表示$i$的拆分数,那么$g[i]=\sum_{j=0}^{m}g[i-j]$,这显然可以用矩阵表示,设转移矩阵为$A$。

然后我们设$f[i]$表示字符串到$i$的方案数。我们可以发现$A^{a1+a2+...+ak}=A^{a1}*A^{a2}*...*A^{ak}$。

那么我们把$f$也变成矩阵,则$f[i]=\sum_{j=0}^{i-1}f[j]*A^{s[j+1]...s[i]}$,因为矩阵可以加法,满足分配律,所以这里是对的。

预处理出$(A^{10^{r}})^{k}$,然后直接$dp$即可。复杂度$O(m^{3}*n^{2})$。

 #include <bits/stdc++.h>
#define il inline
#define RG register
#define ll long long
#define rhl (998244353) using namespace std; struct data{ int m[][]; }A[][],f[],now; char s[];
int n,m; il int gi(){
RG int x=,q=; RG char ch=getchar();
while ((ch<'' || ch>'') && ch!='-') ch=getchar();
if (ch=='-') q=-,ch=getchar();
while (ch>='' && ch<='') x=x*+ch-,ch=getchar();
return q*x;
} il void add(data &a,data b){
for (RG int i=;i<=m;++i)
for (RG int j=;j<=m;++j){
a.m[i][j]+=b.m[i][j];
if (a.m[i][j]>=rhl) a.m[i][j]-=rhl;
}
return;
} il data mul(data a,data b){
data c; memset(c.m,,sizeof(c.m));
for (RG int i=;i<=m;++i)
for (RG int j=;j<=m;++j)
for (RG int k=;k<=m;++k)
c.m[i][k]=(1LL*a.m[i][j]*b.m[j][k]+c.m[i][k])%rhl;
return c;
} int main(){
#ifndef ONLINE_JUDGE
freopen("split.in","r",stdin);
freopen("split.out","w",stdout);
#endif
scanf("%s",s+),n=strlen(s+),m=gi();
for (RG int i=;i<=m;++i)
for (RG int j=;j<=m;++j) A[][].m[i][j]=i==j;
for (RG int i=;i<m;++i) A[][].m[i+][i]=;
for (RG int i=;i<=m;++i) A[][].m[i][m]=;
for (RG int i=;i<;++i) A[][i]=mul(A[][i-],A[][]);
for (RG int i=;i<=n;++i){
A[i][]=A[][],A[i][]=mul(A[i-][],A[i-][]);
for (RG int j=;j<;++j) A[i][j]=mul(A[i][j-],A[i][]);
}
f[]=A[][];
for (RG int i=;i<=n;++i){
now=A[][s[i]-''];
for (RG int j=i-;~j;--j){
add(f[i],mul(f[j],now));
if (j) now=mul(A[i-j][s[j]-''],now);
}
}
cout<<f[n].m[m][m]; return ;
}

bzoj4037 [HAOI2015]数字串拆分的更多相关文章

  1. BZOJ4037:[HAOI2015]数字串拆分——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=4037 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时 ...

  2. [HAOI2015]数字串拆分

    题目描述 你有一个长度为n的数字串.定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5,分别为4=1+1+1+1你可以将这个数字串分割成若干个数字(允许前导0),将他们加 ...

  3. 洛谷3176 [HAOI2015]数字串拆分 (矩阵乘法+dp)

    qwq真的是一道好题qwq自己做基本是必不可能做出来的. 首先,如果这个题目只是求一个\(f\)数组的话,那就是一道裸题. 首先,根据样例 根据题目描述,我们能发现其实同样数字的不同排列,也是属于不同 ...

  4. BZOJ 4037 [HAOI2015]数字串拆分 ——动态规划

    拆分的情况下,发现f数组本身并不是很好递推. 因为f(123)=f(123)/f(12+3)/f(1+2+3). 然后考虑f可以怎么表示f(n)=a0*M^n M为转移矩阵. 然后发现 f(x+y)= ...

  5. bzoj 4037: [HAOI2015]数字串拆分【dp+矩阵加速】

    首先f长得就很像能矩阵优化的,先构造转移矩阵(这里有一点神奇的地方,我看网上的blog和我构造的矩阵完全不一样还以为我的构造能力又丧失了,后来惊奇的发现我把那篇blog里的构造矩阵部分换成我的构造方式 ...

  6. loj#2128. 「HAOI2015」数字串拆分 矩阵乘法

    目录 题目链接 题解 代码 题目链接 loj#2128. 「HAOI2015」数字串拆分 题解 \(f(s)\)对于\(f(i) = \sum_{j = i - m}^{i - 1}f(j)\) 这个 ...

  7. 【LOJ】#2128. 「HAOI2015」数字串拆分

    题解 题中给的函数可以用矩阵快速幂递推 我们记一个数组dp[i](这个数组每个元素是一个矩阵)表示从1到i所有的数字经过拆分矩阵递推的加和 转移方法是 \(dp[i] = \sum_{j = 0}^{ ...

  8. 解决 PHPExcel 长数字串显示为科学计数

    解决 PHPExcel 长数字串显示为科学计数 在excel中如果在一个默认的格中输入或复制超长数字字符串,它会显示为科学计算法,例如身份证号码,解决方法是把表格设置文本格式或在输入前加一个单引号. ...

  9. Openjudge 1.13-40 提取数字串按数值排序

    40:提取数字串按数值排序 查看 总时间限制:  1000ms 内存限制:  65536kB 描述 给定一个字符串,请将其中的所有数字串提取,并将每个数字串作为整数看待(假设可以用int 表示),按从 ...

随机推荐

  1. 在ASP.NET中过滤HTML字符串总结

    先记下来,以作备用! ///   <summary>去除HTML标记 /// ///   </summary> ///   <param name="Htmls ...

  2. 常见IT英语单词

    lable标签,master精通.主人,reference参考,release发布,schema模式,component组件,persistence持久化,generate生成产生,plugin插件, ...

  3. 01:谁考了第k名 个人博客:doubleq.win

    个人博客:doubleq.win 01:谁考了第k名 查看 提交 统计 提问 总时间限制:  1000ms 内存限制:  65536kB 描述 在一次考试中,每个学生的成绩都不相同,现知道了每个学生的 ...

  4. 【Android】利用回收机制创建ListView列表实现

    MainActivity.java package com.glandroid.listviewdemo; import android.graphics.Color; import android. ...

  5. AngularJS开发人员最常犯的10个错误

    简介AngularJS是目前最为活跃的Javascript框架之一,AngularJS的目标之一是简化开发过程,这使得AngularJS非常善于构建小型app原型,但AngularJS对于全功能的客户 ...

  6. Google Protocol Buffer 的使用(未完待续)

    简介 Google Protocol Buffer( 简称 Protobuf) 是 Google 公司内部的混合语言数据标准,目前已经正在使用的有超过 48,162 种报文格式定义和超过 12,183 ...

  7. Conda常用命令整理

    主要参考Anaconda官方指南Using Conda:https://conda.io/docs/using/index.html 环境:Win10 64bit with conda 4.3.14  ...

  8. OSMC Vs. OpenELEC Vs. LibreELEC – Kodi Operating System Comparison

    Kodi's two slim-and-trim kid brothers LibreELEC and OpenELEC were once great solutions for getting t ...

  9. Mac怎么生成.ssh文件

    可使用如下命令生成 1 ssh-keygen -t rsa 因为mac系统也是从unix基础上演变过来的,所以很多核心的东西也是与unix相通的. 1.-t 是指定加密参数为ras,默认是dsa 2. ...

  10. Bitmap到底占多少内存

    转至:Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存? Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟 ...