题目大意:有一个长度为n的数字串
定义f(S)为将S拆分成若干个1~m的数的和的方案数
你可以将这个数字串分割成若干个数字(允许前导0),将他们加起来,求f,并求和
已知字符串和m后求答案模998244353
题解:丢题解跑……
我的收获:emmm
#include<iostream>
#include<cstdio>
#include<cstring>
#define ll long long
#define mod 998244353
#define N 1005
using namespace std;
struct matrix{ int p[7][7]; }c[15][N],dp[N],a;
int s[N],n,m; char ch[N];
matrix operator *(matrix x,matrix y){
int i,j,k; matrix z;
for (i=1; i<=m; i++)
for (j=1; j<=m; j++){
ll tmp=0;
for (k=1; k<=m; k++) tmp+=(ll)x.p[i][k]*y.p[k][j];
z.p[i][j]=tmp%mod;
}
return z;
}
matrix operator +(matrix x,matrix y){
int i,j;
for (i=1; i<=m; i++)
for (j=1; j<=m; j++){
x.p[i][j]+=y.p[i][j]; if (x.p[i][j]>=mod) x.p[i][j]-=mod;
}
return x;
}
matrix ksm(matrix x,int y){
matrix z=x;
for (y--; y; y>>=1,x=x*x) if (y&1) z=z*x; return z;
}
int main(){
scanf("%s",ch+1); n=strlen(ch+1); int i,j;
scanf("%d",&m);
for (i=1; i<=n; i++) s[i]=ch[i]-'0';
for (i=1; i<=m; i++){
a.p[i][m]=c[0][1].p[i][i]=1;
if (i>1) a.p[i][i-1]=1;
}
for (i=1; i<=9; i++){
c[i][1]=c[i-1][1]*a;
for (j=2; j<=n; j++) c[i][j]=ksm(c[i][j-1],10);
}
dp[0].p[1][m]=1; matrix tmp;
for (i=1; i<=n; i++){
tmp=c[s[i]][1];
for (j=i-1; j>=0; j--){
dp[i]=dp[i]+dp[j]*tmp;
if (j && s[j]) tmp=tmp*c[s[j]][i-j+1];
}
}
printf("%d\n",dp[n].p[1][m]);
return 0;
}