This topic is even more amazing. It is said to be an enhanced version of the previous question.
The meaning of the question is the total number of cases where M mode strings are given, and then the length of L is given, and the text not exceeding L contains at least one mode.
You can also create a Trie graph using a pattern string, and create a matrix M with a path length of 1 according to the Trie graph.
The total number of cases is 26 ^ 1 + 26 ^ 2 +... + 26 ^ L. The total number of cases without a mode string is matrix N = M ^ 1 + M ^ 2 + M ^ 3
+... + M ^ L is the sum of the first row. The answer is the total number of cases minus the list containing no mode strings.
Some matrix algorithms are used here, such as fast and fast sums. However, I use Operator overloading, which is the most tragic
The operator after overload has no priority, and I still use it as a priority, so it is a tragedy... Never passed the sample
Go... Alas, I finally found this problem... I wrote about 260 lines of code. The previous code can be used as a moment.
Array Operation template... The Trie graph is also good. It may be printed in a few days...
The Code is as follows:
# Include <stdio. h>
# Include <string. h>
# Include <queue>
# Include <algorithm>
Using namespace std;
Typedef unsigned long INT;
Const int MAX_D = 26;
Const int MAX_L = 10;
Const int MAX_N = 10;
Char szPat [MAX_L];
Const int MAX_S = 31;
Struct Matrix
{
Int nSize;
INT nD [MAX_S] [MAX_S];
Matrix (int nS)
{
Clear (nS );
}
Matrix & operator = (const Matrix & m)
{
NSize = m. nSize;
For (int I = 0; I <nSize; ++ I)
{
For (int j = 0; j <nSize; ++ j)
{
ND [I] [j] = m. nD [I] [j];
}
}
Return * this;
}
Void Clear (int nS)
{
NSize = nS;
Memset (nD, 0, sizeof (nD ));
}
Void Unit ()
{
For (int I = 0; I <nSize; ++ I)
{
For (int j = 0; j <nSize; ++ j)
{
ND [I] [j] = (I = j? 1: 0 );
}
}
}
};
Matrix operator + (const Matrix & A, const Matrix & B)
{
Matrix C (A. nSize );
For (int I = 0; I <A. nSize; ++ I)
{
For (int j = 0; j <A. nSize; ++ j)
{
C. nD [I] [j] = A. nD [I] [j] + B. nD [I] [j];
}
}
Return C;
}
Matrix operator * (const Matrix & nA, const Matrix & nB)
{
Matrix nC (nB. nSize );
For (int I = 0; I <nA. nSize; ++ I)
{
For (int j = 0; j <nA. nSize; ++ j)
{
For (int k = 0; k <nA. nSize; ++ k)
{
NC. nD [I] [j] + = nA. nD [I] [k] * nB. nD [k] [j];
}
}
}
Return nC;
}
Matrix operator ^ (Matrix B, INT nExp)
{
Matrix ans (B. nSize );
Ans. Unit ();
While (nExp)
{
If (nExp % 2)
{
Ans = ans * B;
}
B = B * B;
NExp> = 1;
}
Return ans;
}
// Calculate base ^ 1 + base ^ 2 + base ^ N
Matrix SumPowMatrix (Matrix & base, INT nN)
{
If (nN = 1)
{
Return base;
}
Matrix ans = SumPowMatrix (base, nN/2 );
Ans = ans + (base ^ (nN/2) * ans); // The overload operator does not guarantee the priority.
If (nN % 2)
{
Ans = ans + (base ^ nN); // no priority. It must be enclosed in brackets. It has been detected for 2 hours.
}
Return ans;
}
Struct Trie
{
Trie * next [MAX_D];
Trie * fail;
Int no;
Bool flag;
};
Trie tries [MAX_L * MAX_N];
Int nP;
Trie * pRoot;
Trie * NewNode ()
{
Memset (& tries [nP], 0, sizeof (Trie ));
Tries [nP]. no = nP;
Return & tries [nP ++];
}
Void InitTrie (Trie * & pRoot)
{
NP = 0;
PRoot = NewNode ();
}
Void Insert (Trie * pRoot, char * pszPat)
{
Trie * pNode = pRoot;
While (* pszPat)
{
Int idx = * pszPat-'A ';
If (pNode-> next [idx] = NULL)
{
PNode-> next [idx] = NewNode ();
}
PNode = pNode-> next [idx];
++ PszPat;
}
PNode-> flag = true;
}
Void BuildAC (Trie * pRoot, Matrix & M)
{
PRoot-> fail = NULL;
Queue <Trie *> qt;
Qt. push (pRoot );
M. Clear (nP );
While (! Qt. empty ())
{
Trie * front = qt. front ();
Qt. pop ();
For (int I = 0; I <MAX_D; ++ I)
{
If (front-> next [I])
{
Trie * pNode = front-> fail;
While (pNode & pNode-> next [I] = NULL)
{
PNode = pNode-> fail;
}
Front-> next [I]-> fail = pNode? PNode-> next [I]: pRoot;
If (front-> next [I]-> fail-> flag)
{
Front-> next [I]-> flag = true;
}
Qt. push (front-> next [I]);
}
Else
{
Front-> next [I] = front = pRoot? PRoot: front-> fail-> next [I];
}
// Must the front-> flag be set to false? Adding or not generates different matrices
If (! Front-> next [I]-> flag)
{
+ M. nD [front-> no] [front-> next [I]-> no];
}
}
}
}
Int main ()
{
Int nN;
INT nL;
Matrix M (0 );
While (scanf ("% d % I64u", & nN, & nL) = 2)
{
InitTrie (pRoot );
While (nN --)
{
Scanf ("% s", szPat );
Insert (pRoot, szPat );
}
BuildAC (pRoot, M );
Matrix tmp (1 );
Tmp. nD [0] [0] = 26;
Tmp = SumPowMatrix (tmp, nL );
INT nAns = tmp. nD [0] [0];
Matrix msum = SumPowMatrix (M, nL );
For (int I = 0; I <msum. nSize; ++ I)
{
NAns-= msum. nD [0] [I];
}
Printf ("% I64u \ n", nAns );
}
Return 0;
}