分析
設
邊界:
轉移:
答案:
求
動規不能直接求,不然
用矩陣快速冪。
代碼
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
using namespace std;
const int L=25;
struct Matrix
{
int w,h;
int p[L][L];
}f,v,r;
int n,m,k,res;
char s[L]; int pre[L];
Matrix mutiply(Matrix ma,Matrix mb)
{
Matrix rr;
memset(rr.p,0,sizeof rr.p);
rr.h=ma.h,rr.w=mb.w;
for (int i=0;i<rr.h;i++)
for (int j=0;j<rr.w;j++)
for (int d=0;d<ma.w;d++)
(rr.p[i][j]+=ma.p[i][d]*mb.p[d][j])%=k;
return rr;
}
Matrix mi(Matrix b,int i)
{
if (i==1) return b;
Matrix sum=mi(b,i>>1);
sum=mutiply(sum,sum);
if (i&1) sum=mutiply(sum,b);
return sum;
}
int main(void)
{
scanf("%d%d%d%s",&n,&m,&k,&s[1]);
int j=0;
for (int i=2;i<=m;i++)
{
for (;j&&s[i]^s[j+1];j=pre[j]);
pre[i]=j+=s[i]==s[j+1];
}
int sum;
for (int i=0;i<m;i++)
for (char c='0';c<='9';c++)
{
for (j=i;j&&s[j+1]^c;j=pre[j]);
j+=s[j+1]==c;
if (j^m) v.p[i][j]++;
}
v.w=v.h=m;
f.p[0][0]=1,f.h=1,f.w=m;
r=mutiply(f,mi(v,n));
for (int i=0;i<m;i++) (res+=r.p[0][i])%=k;
printf("%d\n",res);
return 0;
}