- 给定的链可能有重复
- 快速幂如果用递归会爆栈
#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<map>
#include<string>
#include<iostream>
using namespace std;
using namespace std;
typedef long long ll;
const ll mod=1000000007;
int n;
ll m;
struct Matrix
{
ll mp[60][60];
Matrix()
{
memset(mp,0,sizeof(mp));
}
};
Matrix mul(Matrix a,Matrix b)
{
int i,j,k;
Matrix c;
for(i=0; i<n; i++)
{
for(j=0; j<n; j++)
{
c.mp[i][j]=0;
for(k=0; k<n; k++)
{
c.mp[i][j]=(c.mp[i][j]+a.mp[i][k]*b.mp[k][j])%mod;
}
}
}
return c;
}
Matrix mypow(Matrix t,ll x)
{
Matrix c;
for(int i=0; i<n; i++)
c.mp[i][i]=1;
while(x)
{
if(x&1)
c=mul(c,t);
t=mul(t,t);
x>>=1;
}
return c;
}
int get(char a[],char b[])
{
string t1,t2;
int len1=strlen(a),len2=strlen(b);
int len=min(len1,len2);
for(int i=2; i<=len; i++)
{
t1="";
t2="";
for(int j=len1-i; j<len1; j++)
t1+=a[j];
for(int j=0; j<i; j++)
t2+=b[j];
if(t1==t2)
{
return 1;
}
}
return 0;
}
map<string,int>mp;
int main()
{
string ss;
char s[100][100];
int _,cnt;
ll ans;
scanf("%d",&_);
Matrix a;
while(_--)
{
scanf("%d%lld",&n,&m);
mp.clear();
cnt=0;
memset(s,0,sizeof(s));
for(int i=0; i<n; i++)
{
cin>>ss;
if(mp[ss]==0)
{
mp[ss]++;
for(int j=0; j<ss.size(); j++)
{
s[cnt][j]=ss[j];
}
cnt++;
}
}
n=cnt;
for(int i=0; i<n; i++)
{
for(int j=0; j<n; j++)
{
a.mp[i][j]=get(s[i],s[j]);
}
}
a=mypow(a,m-1);
ans=0;
for(int i=0; i<n; i++)
for(int j=0; j<n; j++)
ans=(ans+a.mp[i][j])%mod;
printf("%lld\n",ans);
}
return 0;
}