http://acm.hdu.edu.cn/showproblem.php?pid=2243
Problem description Back words, is always an important part of reviewing English. After wasting 3 years of college life, Lele finally began to recite words.
One day, Lele in a word book to see a way to memorize words based on the root. For example, "AB", put in front of the word generally said "contrary, bad, leave" and so on.
So Lele thought, if the back of the root of n, then these roots in the end will appear in the word. The more accurate description is: the length of not more than L, consisting only of lowercase letters, at least a word containing a root, how many of them altogether? This does not consider whether the words have practical meaning.
For example, there are 2 root AA and AB, there may be 104 words with a length of not more than 3, respectively,
(2) Aa,ab,
(26) Aaa,aab,aac...aaz,
(26) Aba,abb,abc...abz,
(25) Baa,caa,daa...zaa,
(25) Bab,cab,dab...zab.
This is only a small case. And for other complex points of the situation, Lele is not a number, please help him now.
Input This topic contains multiple sets of data, please process to the end of the file.
Each group of data occupies two rows.
The first line has two positive integers n and L. (0<n<6,0<l<2^31)
The second line has n roots, each of which consists only of lowercase letters and not more than 5 in length. The middle of two stems is separated by a space.
Output for each set of data, print out the total number of possible words in a row.
Because the results can be very large, you only need to output the value of the 2^64 of the total number of words.
Sample Input
2 3AA AB1 2a
Sample Output
10452
/***hdu2243 ac automata + Matrix multiplication topic: given n words, the number of strings with a given word in a string that is not longer than M is the solution to the problem: the use of AC automata can create a matrix, a few powers of the matrix can be counted the length of the number of strings without the pattern string. Then, the matrix is added to a column, and the number of the column is assigned 1, you can in the transfer process to count the prefix and (very clever). Then the total number minus all the pattern strings is the one that contains the pattern string. The total number of methods see code comments. The number needs to 2^64, the direct definition unsigned long long let its natural overflow can be */#include <stdio.h> #include <string.h> #include <alg orithm> #include <queue> #include <iostream>using namespace std;typedef unsigned long long ull;struct matrix///tectonic matrix {ULL mat[40][40]; int n; Matrix () {} matrix (int _n) {n=_n; for (int i=0, i<n; i++) {for (int j=0; j<n; J + +) {mat[i][j]=0; }}} Matrix operator * (const matrix &B) Const {Matrix Ret=matrix (n); for (int i=0, i<n; i++) {for (int j=0; j<n; J + +) {for (int k=0; k<n; k + +) {Ret.mat[i][j]+=mat[i][k]*b.mat[k][j]; } } } return ret; }}; ULL pow_m (ULL a,int N)///fast power {ULL ret=1; ULL Tmp=a; while (n) {if (n&1) ret*=tmp; tmp*=tmp; n>>=1; } return ret;} Matrix Pow_m (Matrix A,int N)///matrix fast Power {matrix Ret=matrix (A.N); for (int i=0; i<a.n; i++) {ret.mat[i][i]=1; } Matrix Tmp=a; while (n) {if (n&1) ret=ret*tmp; tmp=tmp*tmp; n>>=1; } return ret;} struct trie{int next[40][26],fail[40]; BOOL END[40]; int root,l; int NewNode () {for (int i=0; i<26; i++) next[l][i]=-1; End[l++]=false; return L-1; } void Init () {l=0; Root=newnode (); } void Insert (char *buf) {int Len=strlen (BUF); int now=root; for (int i=0; i<len; i++) {if (next[now][buf[i]-' a ']==-1) next[now][buf[i]-' a ']=newnode (); Now=next[now][buf[i]-' a ']; } end[now]=true; } void Build () {queue<int>q; Fail[root]=root; for (int i=0; i<26; i++) {if (next[root][i]==-1) {next[root][i]=root; } else {fail[next[root][i]]=root; Q.push (Next[root][i]); }} while (! Q.empty ()) {int Now=q.front (); Q.pop (); if (End[fail[now]]) end[now]=true; for (int i=0; i<26; i++) {if (next[now][i]==-1) {next[now][ I]=next[fail[now]][i]; } else {fail[next[now][i]]=next[fail[now]][i]; Q.push (Next[now][i]); }}}} Matrix Getmatrix ()///Get the state transfer matrix, add a column, each multiplication can be the previous and mat[0][l+1] {matrix Ret=matrix ( L+1); for (int i=0, i<l; i++) {for (int j=0; j<26; j + +) {if (end[next[i][j]]==false) ret.mat[i][next[i][j]]++; }} for (int i=0; i<l+1; i++) {ret.mat[i][l]=1; } return ret; }} Ac;char Buf[10];int main () {int n,l; while (~SCANF ("%d%d", &n,&l)) {ac.init (); for (int i=0; i<n; i++) {scanf ("%s", buf); Ac.insert (BUF); } ac.build (); Matrix A=ac.getmatrix (); A=pow_m (a,l); ULL res=0; for (int i=0; i<a.n; i++) {res+=a.mat[0][i]; } res--; /* * f[n]=1 + 26^1 + 26^2 + ... 26^n * f[n]=26*f[n-1]+1 * {f[n] 1} = {f[n-1] 1}[26 0; 1 1] * number is f[l]-1; * The l<2^31 of the problem. The power of the matrix cannot be l+1 times, otherwise it will time out./A=matrix (2); a.mat[0][0]=26; A.mat[1][0]=a.mat[1][1]=1; A=pow_m (a,l); ULL Ans=a.mat[1][0]+a.mat[0][0]; ans--; Ans-=res; cout << ans<<endl; } return 0;}
hdu2243 ac automata + matrix multiplication