[HAOI2015]数字串拆分
题目描述
你有一个长度为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,一个质数)取模后的值。
输入输出格式
输入格式:第一行输入一个字符串,第二行输入m
输出格式:仅输出一个数表示答案
输入输出样例
说明
对于100%的数据,字符串长度不超过500,m<=5
先求出$f[s]$
显然$f[i]=\sum_{j=i-m}^{i-1}f[j]$
如果i特别大就可以用一个m*m的转移矩阵
也就是$(f_{i-m+1},f_{i-m+2},...f_{i})$的转移矩阵
预处理出A[i][j]表示数S为j*10^i的转移矩阵
对于$g$的转移:
显然$g[i]=\sum_{j=0}^{i-1}g[j]*D[j+1][i]$
$D[j+1][i]$表示j+1~i位构成的数的转移矩阵,显然可以通过A推出
g也要用一个矩阵表示
g[0]初始矩阵使$g_0=1$,也就是$(0,0,..,0,1)$
最后输出矩阵中代表$g_n$的方案,位置是(1,m)
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 int Mod=998244353; 8 struct Matrix 9 { 10 int a[6][6]; 11 }f[501],A[501][10],now; 12 char s[502]; 13 int n,m,ans; 14 Matrix operator *(const Matrix &a,const Matrix &b) 15 { 16 int i,j,l; 17 Matrix res; 18 memset(res.a,0,sizeof(res.a)); 19 for (i=1; i<=m; i++) 20 { 21 for (j=1; j<=m; j++) 22 { 23 for (l=1; l<=m; l++) 24 { 25 res.a[i][j]+=1ll*a.a[i][l]*b.a[l][j]%Mod; 26 if (res.a[i][j]>=Mod) 27 res.a[i][j]-=Mod; 28 } 29 } 30 } 31 return res; 32 } 33 Matrix operator +(const Matrix &a,const Matrix &b) 34 { 35 int i,j,l; 36 Matrix res; 37 memset(res.a,0,sizeof(res.a)); 38 for (i=1; i<=m; i++) 39 { 40 for (j=1; j<=m; j++) 41 { 42 res.a[i][j]=(a.a[i][j]+b.a[i][j])%Mod; 43 } 44 } 45 return res; 46 } 47 int main() 48 {int i,j; 49 cin>>s+1; 50 n=strlen(s+1); 51 cin>>m; 52 for (i=1;i<=m;i++) 53 { 54 A[0][0].a[i][i]=1; 55 } 56 for (i=1;i<=m;i++) 57 { 58 A[0][1].a[i][m]=1; 59 } 60 for (i=1;i<m;i++) 61 { 62 A[0][1].a[i+1][i]=1; 63 } 64 for (i=2;i<=9;i++) 65 { 66 A[0][i]=A[0][i-1]*A[0][1]; 67 } 68 for (i=1;i<=n;i++) 69 { 70 A[i][0]=A[0][0]; 71 A[i][1]=A[i-1][9]*A[i-1][1]; 72 for (j=2;j<=9;j++) 73 { 74 A[i][j]=A[i][j-1]*A[i][1]; 75 } 76 } 77 f[0].a[1][m]=1; 78 for (i=1;i<=n;i++) 79 { 80 now=A[0][s[i]-'0']; 81 for (j=i-1;j>=0;j--) 82 { 83 f[i]=f[i]+(f[j]*now); 84 if (j) now=A[i-j][s[j]-'0']*now; 85 } 86 } 87 ans=f[n].a[1][m]; 88 cout<<ans; 89 }