自动机之后按照自动机上的状态转移做dp就可以了
不用矩乘还是很良心
1 const mo=10007; 2 var q,f:array[0..10010] of longint; 3 trie:array[0..10010,'A'..'Z'] of longint; 4 can:array[0..10010] of boolean; 5 dp:array[0..105,0..10010] of longint; 6 l,k,s0,ss,i,n,m,j,t:longint; 7 s:string; 8 c:char; 9 10 procedure bfs; 11 var x,y,i,h,r:longint; 12 c:char; 13 begin 14 h:=1; 15 r:=0; 16 for c:='A' to 'Z' do 17 if trie[0,c]>0 then 18 begin 19 inc(r); 20 q[r]:=trie[0,c]; 21 end; 22 while h<=r do 23 begin 24 x:=q[h]; 25 for c:='A' to 'Z' do 26 if trie[x,c]>0 then 27 begin 28 y:=trie[x,c]; 29 i:=f[x]; 30 while (i>0) and (trie[i,c]=0) do i:=f[i]; 31 if can[trie[i,c]] then can[y]:=true; //这是一个易错点,考虑下shen和he这两个单词 32 f[y]:=trie[i,c]; 33 inc(r); 34 q[r]:=y; 35 end; 36 inc(h); 37 end; 38 end; 39 40 begin 41 readln(n,m); 42 f[0]:=-1; 43 for i:=1 to n do 44 begin 45 readln(s); 46 j:=0; 47 l:=length(s); 48 for k:=1 to l do 49 begin 50 if trie[j,s[k]]=0 then 51 begin 52 inc(t); 53 trie[j,s[k]]:=t; 54 end; 55 j:=trie[j,s[k]]; 56 end; 57 can[j]:=true; 58 end; 59 bfs; 60 s0:=1; 61 for i:=1 to m do 62 s0:=s0*26 mod mo; 63 dp[0,0]:=1; 64 for i:=1 to m do 65 for j:=0 to t do 66 begin 67 if can[j] then continue; 68 for c:='A' to 'Z' do 69 begin 70 k:=j; 71 while (k<>-1) do 72 begin 73 if trie[k,c]>0 then 74 begin 75 dp[i,trie[k,c]]:=(dp[i,trie[k,c]]+dp[i-1,j]) mod mo; 76 break; 77 end; 78 k:=f[k]; 79 end; 80 if k=-1 then 81 dp[i,0]:=(dp[i,0]+dp[i-1,j]) mod mo; 82 end; 83 end; 84 85 ss:=0; 86 for i:=0 to t do 87 if not can[i] then ss:=(ss+dp[m,i]) mod mo; 88 writeln((s0+mo-ss) mod mo); 89 end.