博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【LOJ】#2128. 「HAOI2015」数字串拆分
阅读量:5152 次
发布时间:2019-06-13

本文共 2863 字,大约阅读时间需要 9 分钟。

题解

题中给的函数可以用矩阵快速幂递推

我们记一个数组dp[i](这个数组每个元素是一个矩阵)表示从1到i所有的数字经过拆分矩阵递推的加和

转移方法是

\(dp[i] = \sum_{j = 0}^{i - 1} dp[j] * tr[j + 1][i]\)
\(tr[j][i]\)表示矩阵的\([j,i]\)组成的数字次幂是什么样的矩阵

代码

#include 
#define fi first#define se second#define pii pair
#define mp make_pair#define pb push_back#define enter putchar('\n')#define space putchar(' ')#define MAXN 100005#define mo 994711//#define ivorysiusing namespace std;typedef long long int64;typedef long double db;typedef unsigned int u32;template
void read(T &res) { res = 0;char c = getchar();T f = 1; while(c < '0' || c > '9') { if(c == '-') f = -1; c = getchar(); } while(c >= '0' && c <= '9') { res = res * 10 + c - '0'; c = getchar(); } res *= f;}template
void out(T x) { if(x < 0) {putchar('-');x = -x;} if(x >= 10) out(x / 10); putchar('0' + x % 10);}const int MOD = 998244353;int M,N;char s[505];int inc(int a,int b) { return a + b >= MOD ? a + b - MOD : a + b;}int mul(int a,int b) { return 1LL * a * b % MOD;}struct Matrix { int f[6][6]; Matrix() {memset(f,0,sizeof(f));} friend Matrix operator * (const Matrix &a,const Matrix &b) { Matrix c; for(int i = 0 ; i < M ; ++i) { for(int j = 0 ; j < M ; ++j) { for(int k = 0 ; k < M ; ++k) { c.f[i][j] = inc(c.f[i][j],mul(a.f[i][k],b.f[k][j])); } } } return c; } friend Matrix operator + (const Matrix &a,const Matrix &b) { Matrix c; for(int i = 0 ; i < M ; ++i) { for(int j = 0 ; j < M ; ++j) { c.f[i][j] = inc(a.f[i][j],b.f[i][j]); } } return c; }}A[15],dp[505],tr[505][505];int g[15];Matrix fpow(Matrix x,int c) { Matrix res = A[0],t = x; while(c) { if(c & 1) res = res * t; t = t * t; c >>= 1; } return res;}void Solve() { scanf("%s",s + 1); read(M);N = strlen(s + 1); for(int i = 0 ; i < M ; ++i) { A[0].f[i][i] = 1; } dp[0] = A[0]; g[0] = 1; for(int i = 1 ; i < M ; ++i) { for(int j = 1 ; j <= i ; ++j) { g[i] = inc(g[i - j],g[i]); } } for(int i = 0 ; i < M ; ++i) { if(i != M - 1) A[1].f[i][i + 1] = 1; A[1].f[M - 1][i] = 1; } for(int i = 2 ; i <= 9 ; ++i) { A[i] = A[i - 1] * A[1]; } for(int i = 1 ; i <= N ; ++i) { Matrix r = A[0],t; for(int j = i ; j <= N; ++j) { r = r * r;t = r; r = r * r;r = r * r;r = r * t; r = r * A[s[j] - '0']; tr[i][j] = r; } } for(int i = 1 ; i <= N ; ++i) { for(int j = 0 ; j < i ; ++j) { dp[i] = dp[i] + dp[j] * tr[j + 1][i]; } } int ans = 0; for(int i = 0 ; i < M ; ++i) ans = inc(ans,mul(g[i],dp[N].f[0][i])); out(ans);enter;}int main() {#ifdef ivorysi freopen("f1.in","r",stdin);#endif Solve(); return 0;}

转载于:https://www.cnblogs.com/ivorysi/p/9674730.html

你可能感兴趣的文章
26、linux 几个C函数,nanosleep,lstat,unlink
查看>>
001.RAID简介
查看>>
投标项目的脚本练习2
查看>>
第五次实验
查看>>
201521123107 《Java程序设计》第9周学习总结
查看>>
runtime的基本应用
查看>>
关于scrollTop的那些事
查看>>
Caroline--chochukmo
查看>>
算法导论笔记 第8章 线性时间排序
查看>>
利用jquery的contains实现搜索功能
查看>>
Xcode 6.2 beta 3 太难下载!下载了,不敢独享
查看>>
并发编程
查看>>
Bootstrap
查看>>
C语言错误: HEAP CORRUPTION DETECTED
查看>>
【Java基础】Java类的加载和对象创建流程的详细分析
查看>>
2018-2019-1 20165231《信息安全系统设计基础》第二周学习总结
查看>>
iOS之文本属性Attributes的使用
查看>>
从.Net版本演变看String和StringBuilder性能之争
查看>>
Excel操作 Microsoft.Office.Interop.Excel.dll的使用
查看>>
XlFileFormat
查看>>