bzoj1009
kmp和矩阵乘法的运用,还是挺明显的
#include<cstdio>
#include<cctype>
using namespace std;
inline void read(int &x){
char ch=getchar();x=0;
for(;!isdigit(ch);ch=getchar());
for(;isdigit(ch);ch=getchar())x=(x<<1)+(x<<3)+ch-'0';
}
char ch[22];
int fl,n,m,mo,f[22],c[22][22],nex[22],a[22][22];
inline int query(int x,int y){return x==y?9:8;}
inline void init(){
f[0]=1;
for(int i=1;i<=m;i++)ch[i]-='0';
for(int t,i=2;i<=m;i++){
for(t=nex[i-1];ch[t+1]!=ch[i] && t;t=nex[t]);
if(ch[t+1]==ch[i])t++;
nex[i]=t;
}
for(int len,i=0;i<m;i++)for(int j=0;j<=9;j++){
if(j==ch[i+1])len=i+1;else{
for(len=nex[i];len && ch[len+1]!=j;len=nex[len]);
if(ch[len+1]==j)len++;
}
if(len==m)continue;
c[i][len]++;
}
}
inline void mul(){
for(int i=0;i<m;i++)a[0][i]=0;
for(int j=0;j<m;j++)
for(int k=0;k<m;k++)
(a[0][j]+=f[k]*c[k][j])%=mo;
for(int i=0;i<=m;i++)f[i]=a[0][i];
}
inline void sqrmul(){
for(int i=0;i<=m;i++)for(int j=0;j<=m;j++)a[i][j]=0;
for(int i=0;i<=m;i++)
for(int j=0;j<=m;j++)
for(int k=0;k<=m;k++)
(a[i][j]+=c[i][k]*c[k][j])%=mo;
for(int i=0;i<=m;i++)for(int j=0;j<=m;j++)c[i][j]=a[i][j];
}
int main(){
read(n),read(m),read(mo);scanf("%s",ch+1);
init();
for(;n;n>>=1,sqrmul())if(n&1)mul();
int ans=0;
for(int i=0;i<m;i++)ans=(ans+f[i])%mo;
printf("%d\n",ans);
return 0;
}