思路:设f[i][j]表示前i位后j位与不吉利串前j位相同的方案数,然后f[i][j]+=f[i-1][k]*trans[k][j],trans[k][j]表示串s后k位与不吉利串前k位相同,添加一个字符后后j位与不吉利串前j位相同的方案数,显然这个矩阵是可以用kmp求的,然后因为只能由i转移到i+1,且转移矩阵是一定的,于是可以用矩阵乘法快速幂优化dp即可。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define maxm 25
int n,m,p;
int next[maxm];
char s[maxm];
struct matrix{
int a[maxm][maxm];
void clear(){memset(a,0,sizeof(a));}
void initialize(){clear();for (int i=0;i<m;i++) a[i][i]=1;}
}trans;
void getnext(){
int len=strlen(s+1);next[1]=0;
for (int i=2,j=0;i<=len;i++){
while (j&&s[j+1]!=s[i]) j=next[j];
if (s[j+1]==s[i]) j++;
next[i]=j;
}
}
void gettrans(){
for (int i=0;i<m;i++)
for (int j=0;j<=9;j++){
int tmp=i;
while (tmp && (s[tmp+1]-'0')!=j) tmp=next[tmp];
if ((s[tmp+1]-'0')==j) trans.a[i][tmp+1]++,trans.a[i][tmp+1]%=p;
else trans.a[i][0]++,trans.a[i][0]%=p;
}
}
matrix mul(matrix a,matrix b){
matrix c;c.clear();
for (int i=0;i<m;i++)
for (int j=0;j<m;j++)
for (int k=0;k<m;k++)
c.a[i][k]=(c.a[i][k]+a.a[i][j]*b.a[j][k]%p)%p;
return c;
}
matrix power(matrix a,int k){
matrix x;x.initialize();
for (;k;k>>=1,a=mul(a,a)) if (k&1) x=mul(x,a);
return x;
}
int main(){
scanf("%d%d%d",&n,&m,&p);
scanf("%s",s+1);
getnext();
gettrans();
matrix tmp=power(trans,n),ans;ans.clear(),ans.a[0][0]=1;int t=0;
ans=mul(ans,tmp);
for (int i=0;i<m;i++) t=(t+ans.a[0][i])%p;
printf("%d\n",t);
return 0;
}