If you want to work out this problem, you need to first understand the two knowledge points:
1, the tree structure dictionary
2, KMP algorithm (i.e. fail configuration pointer)
For a trie, you can look at this big brother:
https://www.cnblogs.com/TheRoadToTheGold/p/6290732.html
For KMP, you can look at this big brother:
https://www.cnblogs.com/SYCstudio/p/7194315.html#4255259 (highly recommended !!!!)
Step :( code for the first two steps are necessary automaton AC)
1, using the provided pattern strings trie structure
2, the configuration of the pointer fail, i.e., the current node pointer fail = fail its parent node pointed to the same child node pointed. For value is defined fail pointer FIFO queue queue to borrow ideas (here is the difficulty, please do not understand the comments section)
3, according to the meaning of the questions constructor query function that returns the number ans
AC Code:
#include <bits / STDC ++ H.> the using namespace STD; typedef Long Long LL; const int MAXN = 1e6 + . 5 ; char T [MAXN], S [MAXN]; struct Tree { int Fail; // mismatch pointer int Son [ 26 ]; // a node has a child node up to 26 int NUM; // marked as the end of this node } the DFA [MAXN]; // trie int CNT = 0 ; void Build ( String S) { int now = 0; // trie current pointer for ( int I = 0 ; I <s.length (); ++ I) { IF (the DFA [now] .son [S [I] - ' A ' ] == 0 ) / / tree child node is not the DFA [now] .son [S [I] - ' a ' ] = CNT ++; // add a node now the DFA = [now] .son [S [I] - ' a ' ]; // downwardly configured } the DFA [now] .num + = . 1 ; // closing tag word } void Get_fail () // constructor pointer fail { Queue < int > Q; for ( int I = 0 ; I < 26 is ; ++ I) { IF (the DFA [ 0 !] .Son [I] = 0 ) { the DFA [the DFA [ 0 ] .son [I] ] .fail = 0 ; // points to the root node, a second layer Q.push (the DFA [ 0 ] .son [I]); // pressed into queue } } the while (! Q.empty ()) { int U = Q.front (); Q.pop (); for (int I = 0 ; I < 26 is ; I ++) // back layer { IF ! (the DFA [U] .son [I] = 0 ) // if this node exists { the DFA [the DFA [U] .son [ I]] fail. = the DFA [the DFA [U] .fail] .son [I]; // same child node corresponding to the value of fail to parent node of the node Q.push (DFA [u] .son [ I]); // queued } the else // If this node does not exist { the DFA [U] .son [I] = the DFA [the DFA [U] .fail] .son [I]; // current node's child nodes points to the current node's child nodes fail } } } } int query(char *s) { int len=strlen(s); int now=0,ans=0; for(int i=0;i<len;++i) { now=DFA[now].son[s[i]-'a']; for(int t=now;t!=0&&DFA[now].num!=-1;++t) { if(DFA[now].num>0) //表示存在结尾 ans+=DFA[now].num; DFA[t].num=-1; //标记已访问过 } } return ans; } int main() { int n; scanf("%d",&n); for(int i=0;i<n;i++) { scanf("%s",t); build(t); } Get_fail(); scanf("%s",s); int ans=query(s); printf("%d\n",ans); return 0; }
AC automaton difficult to understand, forgive me lazy, did not give us a satisfactory resolution, but we have a problem I can comment area private, I'll try to answer them in!