很容易想到暴力的转移:f[i][j]表示较长串的前i个字母,最后和不吉利数字相同的已经有j个。价格数组g[j][k]表示第j个不吉利前缀转移到不吉利前缀k的方案数。然后kmp一下就能求得g数组。看到n是1e9,矩阵快速幂优化即可。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n,m,mod,nxt[25];
char s[25];
struct Matrix {
int g[25][25],n,m;
Matrix () {memset(g,0,sizeof g);n=m=0;}
Matrix operator * (const Matrix &b) const {
Matrix ans;ans.n=n,ans.m=b.m;
for(int i=0;i<=ans.n;i++)
for(int k=0;k<=m;k++)
for(int j=0;j<=ans.m;j++)
ans.g[i][j]=(ans.g[i][j]+g[i][k]*b.g[k][j])%mod;
return ans;
}
}A,B;
Matrix ksm(Matrix a,int z) {
Matrix res=a;
z--;
while(z) {
if(z&1) res=res*a;
a=a*a;
z>>=1;
}
return res;
}
int main() {
scanf("%d%d%d",&m,&n,&mod);
scanf("%s",s);
for(int i=1,j=0;i<n;i++) {
while((s[i]!=s[j])&&j) j=nxt[j];
if(s[i]==s[j]) j++;
nxt[i+1]=j;
}
for(int i=0,j;i<n;i++)
for(int k=0;k<10;k++) {
j=i;while(j&&s[j]!=k+'0') j=nxt[j];
if(s[j]==k+'0') j++;
A.g[i][j]++;
}
A.m=A.n=B.m=n-1;
B.n=0;B.g[0][0]=1;
Matrix ans=B*ksm(A,m);
int cnt=0;
for(int i=0;i<n;i++) cnt=(cnt+ans.g[0][i])%mod;
printf("%d",cnt);
}