令f[i][j]表示前i个字符,匹配到不吉利数字的第j位的方案数枚举第i+1位,通过KMP求出前i+1个字符可以匹配到不吉利数字的第几位,然后就可以递推了,然后发现n太大,那就矩阵呗
(我果然还是太弱)
代码(特色矩乘防伪)
//By AcerMo
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n,m,mod;
int nxt[40];
char hate[40];
struct mtix
{
int x[40][40];
mtix(){memset(x,0,sizeof(x));}
}g,f;
inline int read()
{
int x=0;char ch=getchar();
while (ch>'9'||ch<'0') ch=getchar();
while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
return x;
}
inline mtix mul(mtix a,mtix b)
{
mtix c;
for (int i=0;i<m;i++)
for (int j=0;j<m;j++)
for (int k=0;k<m;k++)
c.x[i][j]=(c.x[i][j]+a.x[i][k]*b.x[k][j])%mod;
return c;
}
inline void mpow(int y)
{
for (int i=0;i<m;i++) f.x[i][i]=1;
for (;y;g=mul(g,g),y>>=1)
if (y&1) f=mul(f,g);
return ;
}
signed main()
{
n=read();m=read();mod=read();scanf("%s",hate+1);
for (int i=2,k=0;i<=m;i++)
{
while (k>0&&hate[k+1]!=hate[i]) k=nxt[k];
if (hate[k+1]==hate[i]) k++;
nxt[i]=k;
}
for (int i=0;i<m;i++)
for (int k=0;k<=9;k++)
{
int e=i;
while (e>0&&hate[e+1]-'0'!=k) e=nxt[e];
if (hate[e+1]-'0'==k) e++;
if (e!=m) g.x[e][i]=(g.x[e][i]+1)%mod;
}
mpow(n);int ans=0;
for (int i=0;i<m;i++) ans=(ans+f.x[i][0])%mod;
cout<<ans;
return 0;
}