先对原串做一次KMP。
先考虑朴素的DP:
设
fi,j
f
i
,
j
表示
F(x)
F
(
x
)
的前
i
i
个字符能匹配到 串第
j
j
位的方案数,结合KMP就可以转移了。
把状态用矩阵表示,对每个 求出答案矩阵和转移矩阵,就可以递推求出答案了。
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const int M=1000000007;
int k,n,m,Res;
int F[N];
char s[N];
inline void Add(int& x,int y){
x=(x+y)%M;
}
struct Matrix{
int a[N][N];
Matrix operator * (Matrix b)const{
Matrix c;
memset(c.a,0,sizeof(c.a));
for(int k=0;k<=n;k++)
for(int i=0;i<=n;i++)
if(a[i][k])
for(int j=0;j<=n;j++)
if(b.a[k][j])Add(c.a[i][j],1ll*a[i][k]*b.a[k][j]%M);
return c;
}
}f[N],Ans[N],t;
inline void Build(){
for(int i=1;i<n;i++){
int j=F[i];
while(j&&s[j]!=s[i])j=F[j];
F[i+1]=s[i]==s[j]?j+1:0;
}
}
inline int Get(int x,int y){
while(x&&s[x]!=y+'0')x=F[x];
return s[x]==y+'0'?x+1:0;
}
int main(){
scanf("%d%d",&n,&m);
scanf("%s",s);
Build();
for(int i=0;i<n;i++)
for(int j=0;j<2;j++){
int t=Get(i,j);
if(t==n)Add(f[j].a[i][F[n]],1);
Add(f[j].a[i][t],1);Add(f[j].a[i][i],1);
}
f[0].a[n][n]=f[1].a[n][n]=2;
t.a[0][0]=1;Ans[0]=t*f[0];Ans[1]=t*f[1];
for(int i=2;i<=m;i++)f[i]=f[i-1]*f[i-2],Ans[i]=Ans[i-1]*f[i-2];
cout<<Ans[m].a[0][n]<<endl;
return 0;
}