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

好久没写矩阵加速了,顺便说一下我的构造方法吧:

首先明确转移矩阵的目的,设m为构成f[i]的最小项f[i-m],也就是f[i]=f[i-m]+f[i-...]+f[i-...]+....,其中i-m是最小的。我们需要构造一个m大小的矩阵,使得{f[i-m],f[i-m+1].....f[i-1}乘上这个正方形矩阵变成{f[i-m+1],f[i-m+2]....f[i]}然后因为矩阵乘法是一行乘一列,所以每个右边的每个f[i]都对应了一行矩阵和左边的每项依次相乘。拿这道题的递推式,m=3为例:



以上,我也不知道我在说什么。

然后这道题的精髓在于它使用f的矩阵进行g的dp。设f[i]为前i位的答案,因为矩阵乘法的结合律,我们可以记\( g[i]=\sum_{j=1}^{m}g[j]*c[j+1][i] \)。然后考虑如何预处理出c,可以设c[i][j]为i这个数(1<=i<=9)的\( j^{10} \)次(假装高精)。

总之,一道好题。

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=505,mod=998244353;
int n,m;
char s[N];
struct qwe
{
int a[7][7];
void init()
{
memset(a,0,sizeof(a));
}
void pre()
{
memset(a,0,sizeof(a));
for(int i=1;i<=m;i++)
a[i][i]=1;
}
qwe operator * (const qwe &b) const
{
qwe c;
c.init();
for(int k=1;k<=m;k++)
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
c.a[i][j]=(c.a[i][j]+1ll*a[i][k]*b.a[k][j]%mod)%mod;
return c;
}
qwe operator + (const qwe &b) const
{
qwe c;
c.init();
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
c.a[i][j]=(b.a[i][j]+a[i][j])%mod;
return c;
}
}f[N],a,c[15][N];
qwe ksm(qwe a,int b)
{
qwe r;
r.pre();
while(b)
{
if(b&1)
r=r*a;
a=a*a;
b>>=1;
}
return r;
}
int main()
{
scanf("%s%d",s+1,&m);
n=strlen(s+1);
for(int i=1;i<=n;i++)
s[i]-='0';
for(int i=1;i<m;i++)
a.a[i][i+1]=1;
for(int i=1;i<=m;i++)
a.a[m][i]=1;
c[0][1].pre();
for(int i=1;i<=9;i++)
{
c[i][1]=c[i-1][1]*a;
for(int j=2;j<=n;j++)
c[i][j]=ksm(c[i][j-1],10);
}
f[0].a[1][m]=1;
for(int i=1;i<=n;i++)
{
qwe tmp=c[s[i]][1];
for(int j=i-1;j>=0;j--)
{
f[i]=f[i]+f[j]*tmp;
if(j&&s[j])
tmp=tmp*c[s[j]][i-j+1];
}
}
printf("%d\n",f[n].a[1][m]);
return 0;
}

bzoj 4037: [HAOI2015]数字串拆分【dp+矩阵加速】的更多相关文章

  1. 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)= ...

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

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

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

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

  4. bzoj4037 [HAOI2015]数字串拆分

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

  5. [HAOI2015]数字串拆分

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

  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. HihoCoder - 1807:好的数字串 (KMP DP)

    Sample Input 6 1212 Sample Output 298 给定一个数字字符串S,如果一个数字字符串(只包含0-9,可以有前导0)中出现且只出现1次S,我们就称这个字符串是好的. 例如 ...

  9. [BZOJ 4033] [HAOI2015] T1 【树形DP】

    题目链接:BZOJ - 4033 题目分析 使用树形DP,用 f[i][j] 表示在以 i 为根的子树,有 j 个黑点的最大权值. 这个权值指的是,这个子树内部的点对间距离的贡献,以及 i 和 Fat ...

随机推荐

  1. bit manipulation

    WIKI Bit manipulation is the act of algorithmically manipulating bits or other pieces of data shorte ...

  2. P2839 畅通工程

    P2839 畅通工程 题目描述 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇.省政府“畅通工程”的目标是使全省任何两个城镇间都可以实现交通(但不一定有直接的道路相连, ...

  3. service mesh架构

    service  mesh 系列文章 https://my.oschina.net/iamlipeng/blog/1631575 http://developer.51cto.com/art/2018 ...

  4. LUA协程复用

    -----协程复用根函数 local function routine(fun, args) while (fun) do fun, args = coroutine.yield(fun(table. ...

  5. [Node.js] Read a File in Node.js with fs.readFile and fs.readFileSync

    We'll read a csv file in node.js both synchronously, and asynchronously. The file we're reading is a ...

  6. js中window.onload 与 jquery中$(document.ready()) 測试

    js中window.onload 与 jquery中$(document.ready())差别,验证代码例如以下(调换js代码和Jquer代码书写顺序測试.执行结果一样.因此与代码书写位置没关系): ...

  7. 网络基础笔记——OSI七层模型

    OSI七层模型 由于整个网络连接的过程相当复杂,包含硬件.软件数据封包与应用程序的互相链接等等.假设想要写一支将联网所有功能都串连在一块的程序.那么当某个小环节出现故障时,整仅仅程序都须要改写.所以我 ...

  8. 使用VLC搭建视频直播服务器

    去年我们信息之夜我们进行过视频直播服务,当时我们使用了WMS(Windows Media Server)实现了这个服务,但是编码是微软的WMV,因而像iPhone/Android这样的智能手机无法观看 ...

  9. iOS 开发者中的个人账号与组织账号之间区别

    苹果对开发者主要分为3类:个人.组织(公司.企业).教育机构.即: 1.个人(Individual) 2.组织(Organizations) 组织类又分为2个小类: (1)公司(Company) (2 ...

  10. LDAP方式连接AD获取用户信息

    LDAP资料介绍可以参考:http://wenku.baidu.com/view/262742f9f705cc17552709f9.html ldap访问AD域的的错误一般会如下格式: Ldap lo ...