rt.矩阵快速幂,莫名其妙RE,本地能过,关 O2 没用。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
using namespace std;
#define ll long long
#define il inline
#define mod 1000000007
il ll read() {
ll x=0,f=1;char c=getchar();
while(c<'0'||c>'9') {if(c=='-') {f=-1;} c=getchar();}
while(c>='0'&&c<='9') {x=(x<<3)+(x<<1)+(c^48);c=getchar();}
return x*f;
}
struct node {
int ch[26],fail;
bool tag;
};
struct Matrix {
int n,a[151][151];
Matrix(){}
Matrix(int _n) {
n=_n;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=0;
}
Matrix operator =(Matrix A) {
n=A.n;
for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) a[i][j]=A.a[i][j];
}
};
node trie[405];
int n,m,L,root,tot;
string ss[55];
char s[105];
il void insert() {
if(!root) root=++tot;
int u=root,l=strlen(s+1);
for(int i=1;i<=l;i++) {
if(!trie[u].ch[s[i]-'a']) trie[u].ch[s[i]-'a']=++tot;
u=trie[u].ch[s[i]-'a'];
}
trie[u].tag=1;
}
il void build() {
queue<int> q;
for(int i=0;i<26;i++) {
if(trie[root].ch[i]) {
q.push(trie[root].ch[i]);
trie[trie[root].ch[i]].fail=root;
}
else trie[root].ch[i]=root;
}
while(!q.empty()) {
int u=q.front();
q.pop();
for(int i=0;i<26;i++) {
if(trie[u].ch[i]) {
trie[trie[u].ch[i]].fail=trie[trie[u].fail].ch[i];
q.push(trie[u].ch[i]);
}
else trie[u].ch[i]=trie[trie[u].fail].ch[i];
trie[trie[u].ch[i]].tag|=trie[trie[trie[u].ch[i]].fail].tag;
}
}
}
Matrix dp,mov,I,Ans,Ans2;
bool vis[105][105];
ll dp_tmp[105][105];
Matrix operator +(Matrix A,Matrix B) {
Ans2.n=A.n;
for(int i=1;i<=A.n;i++) for(int j=1;j<=A.n;j++) Ans2.a[i][j]=(A.a[i][j]+B.a[i][j])%mod;
return Ans2;
}
Matrix operator *(Matrix A,Matrix B) {
Ans2.n=A.n;
for(int i=1;i<=A.n;i++) {
for(int j=1;j<=A.n;j++) {
Ans2.a[i][j]=0;
for(int k=1;k<=A.n;k++) Ans2.a[i][j]=(Ans2.a[i][j]+1ll*A.a[i][k]*B.a[k][j])%mod;
}
}
return Ans2;
}
il Matrix qpow(Matrix A,int b) {
Ans=I;
while(b) {
if(b&1) Ans=Ans*A;
A=A*A;
b>>=1;
}
return Ans;
}
int main() {
n=read(),m=read(),L=read();
for(int i=1,x=0,y=0;i<=n;i++) cin>>ss[i];
for(int i=1;i<=m;i++) {
scanf("%s",s+1);
insert();
}
build();
if(L<=100) {
vis[0][1]=1,dp_tmp[0][1]=1;
for(int i=0;i<L;i++) {
for(int j=1;j<=tot;j++) {
if(!vis[i][j]) continue;
for(int k=1;k<=n;k++) {
if(i+ss[k].length()>L) continue;
int jj=j,ok=1;
for(int id=0;id<ss[k].length();id++) {
jj=trie[jj].ch[ss[k][id]-'a'];
if(trie[jj].tag) ok=0;
}
if(!ok) continue;
vis[i+ss[k].length()][jj]=1;
dp_tmp[i+ss[k].length()][jj]=(dp_tmp[i+ss[k].length()][jj]+dp_tmp[i][j])%mod;
}
}
}
ll ans=0;
for(int i=1;i<=tot;i++) ans=(ans+dp_tmp[L][i])%mod;
printf("%lld\n",ans);
}
else {
I.n=2*tot;
for(int i=1;i<=2*tot;i++) I.a[i][i]=1;
for(int i=1;i<=tot;i++) {
for(int j=1;j<=n;j++) {
int ii=i,ok=trie[i].tag^1;
for(int k=0;k<ss[j].length();k++) {
ii=trie[ii].ch[ss[j][k]-'a'];
if(trie[ii].tag) ok=0;
}
if(!ok) continue;
mov.a[tot*(2-ss[j].length())+i][ii+tot]=(mov.a[n*(2-ss[j].length())+i][ii+tot]+1)%mod;
}
}
mov.n=2*tot;
for(int i=1;i<=tot;i++) mov.a[i+tot][i]=1;
dp.n=2*tot;
dp.a[1][tot+1]=1;
dp=dp*qpow(mov,L);
ll ans=0;
for(int i=tot+1;i<=2*tot;i++) ans=(ans+dp.a[1][i])%mod;
printf("%lld\n",ans);
}
return 0;
}