https://www.lydsy.com/JudgeOnline/problem.php?id=4037

你有一个长度为n的数字串。定义f(S)为将S拆分成若干个1~m的数的和的方案数,比如m=2时,f(4)=5。

你可以将这个数字串分割成若干个数字(允许前导0),将他们加起来,求f,并求和。比如g(123)=f(1+2+3)+f(1+23)+f(12+3)+f(123)。

已知字符串和m后求答案对998244353(7*17*223+1,一个质数)取模后的值。

神仙?(亦或是我从来没见过如此神奇的快速幂于是强行神仙?)

参考:https://blog.csdn.net/H_Anonymity/article/details/78348610

$f$数组一个矩乘快速幂求出,然而并没有卵用。

我们令$f[i]$矩乘所需要的矩阵为$h[i]$。

考虑使用dp求$g$,按位考虑,我们每次加上这位所能带来的贡献。

……或者说,乘上?因为$f(x1+x2)=$初始矩阵$*h[x1]*h[x2]$。

于是令$dp[i]$表示前$i$位的求$g$矩阵,则我们有:

$dp[i]=\sum_{j=0}^{i-1}dp[j]*M_j$,其中$M_j=h[j+1$至$i$字符组成的数$]$。

为了求出$M$,我们可以求$f[i][j]$表示$h[i*10^j]$这样我们就能很快捷的求出来了。

听说这个就是神奇的十进制快速幂??

#include<queue>
#include<cmath>
#include<cstdio>
#include<cctype>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int p=;
const int L=;
char s[L];
int n,m;
struct matrix{
ll g[][];
matrix(){
memset(g,,sizeof(g));
}
inline void one(){
for(int i=;i<m;i++)g[i][i]=;
}
matrix operator *(const matrix &b)const{
matrix c;
for(int i=;i<m;i++)
for(int j=;j<m;j++)
for(int k=;k<m;k++)
(c.g[i][j]+=g[i][k]*b.g[k][j]%p)%=p;
return c;
}
matrix operator +(const matrix &b)const{
matrix c;
for(int i=;i<m;i++)
for(int j=;j<m;j++)
c.g[i][j]=(g[i][j]+b.g[i][j])%p;
return c;
}
}f[][L],dp[L];
matrix qpow(matrix x,ll y){
matrix res;res.one();
while(y){
if(y&)res=res*x;
x=x*x;y>>=;
}
return res;
}
void solve(){
f[][].one();
for(int i=;i<m;i++)f[][].g[i][]=;
for(int i=;i<m;i++)f[][].g[i-][i]=; for(int i=;i<=n;i++)f[][i].one(),f[][i]=qpow(f[][i-],);
for(int i=;i<=;i++)
for(int j=;j<=n;j++)f[i][j]=f[i-][j]*f[][j];
dp[].one();
for(int i=;i<=n;i++){
matrix now=f[s[i]-''][];
for(int j=i-;j>=;j--){
dp[i]=dp[i]+dp[j]*now;
if(j)now=now*f[s[j]-''][i-j];
}
}
}
int main(){
scanf("%s%d",s+,&m);n=strlen(s+);
solve();
printf("%d\n",dp[n].g[][]);
return ;
}

+++++++++++++++++++++++++++++++++++++++++++

+本文作者:luyouqi233。               +

+欢迎访问我的博客:http://www.cnblogs.com/luyouqi233/+

+++++++++++++++++++++++++++++++++++++++++++

BZOJ4037:[HAOI2015]数字串拆分——题解的更多相关文章

  1. bzoj4037 [HAOI2015]数字串拆分

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

  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. 【SIKIA计划】_04_C#中级教程 (2015版)笔记

    IKIC#中级教程 (2015版)正常模式指的是不会影响程序的正常运行.1,在VS中我们使用Console.Write(或者WriteLine)方法向控制台输出变量的值,通过这个我们可以查看变量的值是 ...

  2. SQL Server存储过程用法介绍

    存储过程其实就是已预编译为可执行过程的一个或多个SQL语句. 通过调用和传递参数即可完成该存储过程的功能. 前面有介绍过存储过程的一些语法,但是没有详细示例,今天我们来一起研究一下存储过程. 提高性能 ...

  3. Spring学习(4)IOC容器配置bean:定义与实例化

    一.  IOC容器配置 1. 一些概念 (1)IOC容器: 定义:具有管理对象和管理对象之间的依赖关系的容器. 作用:应用程序无需自己创建对象,对象由IOC容器创建并组装.BeanFactory是IO ...

  4. linux的date命令使用指定时间的加减方法与异常

    在一般网页里,date命令减时间方法为: date -d '-100 days' 我的需求是,在指定时间上减8小时.按一般理解来看,命令写成如下样子(有异常错误的写法): date -d " ...

  5. SharpDevelop 笔记

    1. 下载地址: http://jaist.dl.sourceforge.net/project/sharpdevelop/ 2. 使用 VS2012 去掉编译不通过的 Test ,其它可以运行调试. ...

  6. Python入门学习系列——Python文件和异常

    从文件中读取数据 首先准备一个文本文件,文件中存储着普通文本数据.读取文件需要调用open()和read()函数. 读取整个文件 代码示例: with open('pi_digits.txt') as ...

  7. Django_rest_framework_Serializer

    序列化Serializer 序列化用于对用户请求数据进行验证和数据进行序列化(为了解决queryset序列化问题). 那什么是序列化呢?序列化就是把对象转换成字符串,反序列化就是把字符串转换成对象 m ...

  8. 使用sass与compass合并雪碧图(二)

    上一篇文章介绍了怎样使用compass合并雪碧图,生成的icons.css文件中单位是px,PC端可以直接在html文件中使用,但在移动端,我们需要根据不同分辨率的屏幕,来缩放图片大小,显然使用px单 ...

  9. webpack入门指南-step03

    一.webpack 的使用 webpack简单点来说就就是一个配置文件,所有的魔力都是在这一个文件中发生的. 这个配置文件主要分为三大块 entry 入口文件 让webpack用哪个文件作为项目的入口 ...

  10. Ubuntu16.04下 编译安装 Tensorflow

    安装bazel sudo ./bazel***.sh 输入bazel version 检查是否安装. 编译tensorflow 1)./configure 除了选择支持cuda是y,其余的都选择n. ...