Luo Gu P3796 [template] AC automata (Enhanced) (AC automaton)

Topic links: https://www.luogu.com.cn/problem/P3796

 

AC automaton: complexity $ O ((N + M) \ times L) $, N is the number of the pattern string, L is the average length, M being the length of the article.

 

insert:

  A Trie structure, and a mark at the last of each pattern string, i.e. $ vis $.

 

get_fail:

  BFS be performed on the trie, mismatched pointer points to the root point of the first layer; node after a node pointer to mismatch / mismatch pointer his father / pointed / son nodes have the same position.

  Here's a little optimization: fail is to go looking for the mismatch position and take a point fail in his ch [i] certainly is not. Ch can then use these pointers directly to its fail the ch [I], can be found after such operation, ch [I] of each point directly to the final result of the original mismatch along side stop walking, this is the case, each with a pointer to the object ch, do not fail while walking along has been to see a match at this point there is no ch [i] a.

 

query:

  Solving cycle to the next layer until the fail can not go, note that if j is not the end, then that is ans [0] ++, but does not affect the final result, because statistics from the beginning ...

 

AC Code:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<queue>
 6 using namespace std;
 7 const int N=1000000+100;
 8 const int maxn=505;
 9 int fail[N],ch[N][26],vis[N];
10 int ans[N];
11 string s[maxn];
12 int cnt;
13 void insert(string s,int v){
14     int u=0;
15     int len=s.length();
16     for(int i=0;i<len;i++){
17         int id=s[i]-'a';
18         if(!ch[u][id]) ch[u][id]=++cnt;
19         u=ch[u][id];
20     }
21     vis[u]=v;
22 }
23 void get_fail(){
24     int now=0;
25     queue<int> q;
26     for(int i=0;i<26;i++){
27         if(ch[now][i]){
28             q.push(ch[now][i]);
29             fail[ch[now][i]]=now;
30         }
31     }
32     while(!q.empty()){
33         int u=q.front();
34         q.pop();
35         for(int i=0;i<26;i++){
36             int v=ch[u][i];
37             if(v) fail[v]=ch[fail[u]][i],q.push(v);
38             else ch[u][i]=ch[fail[u]][i];//you hua
39         }
40     }
41 }
42 void query(string s){
43     int now=0;
44     int len=s.length();
45     for(int i=0;i<len;i++){
46         now=ch[now][s[i]-'a'];
47         for(int j=now;j;j=fail[j]) ans[vis[j]]++;
48     }
49 }
50 int main(){
51     int n;
52     while(scanf("%d",&n)){
53         memset(vis,0,sizeof(vis));
54         memset(ans,0,sizeof(ans));
55         memset(ch,0,sizeof(ch));
56         memset(fail,0,sizeof(fail));
57         if(n==0) break;
58         for(int i=1;i<=n;i++){
59             cin>>s[i];
60             insert(s[i],i);
61         }
62         get_fail();
63         string str;
64         cin>>str;
65         query(str);
66         int maxx=0;
67         for(int i=1;i<=n;i++) maxx=max(maxx,ans[i]);
68         printf("%d\n",maxx);
69         for(int i=1;i<=n;i++) if(ans[i]==maxx) cout<<s[i]<<endl;
70     }
71     return 0;
72 }
AC Code

 

Guess you like

Origin www.cnblogs.com/New-ljx/p/12354855.html
Recommended