[洛谷3796]【模板】AC自动机(加强版)

题目大意:
  给定$n(n\leq150)$个模式串$p_i(|p_i|\le70)$和一个$t(|t|\le10^6)$,求$t$中被匹配次数最多的$p_i$。

思路:
  AC自动机。匹配时记录一下匹配次数即可。

 1 #include<queue>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<algorithm>
 5 inline int getint() {
 6     register char ch;
 7     while(!isdigit(ch=getchar()));
 8     register int x=ch^'0';
 9     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
10     return x;
11 }
12 const int N=150,L1=71,L2=1e6+1,S=26;
13 int cnt[N];
14 char s[N][L1],t[L2];
15 class AhoCorasick {
16     private:
17         std::queue<int> q;
18         int val[N*L1]={-1},ch[N*L1][S],fail[N*L1];
19         int sz,new_node() {
20             fail[++sz]=0;
21             val[sz]=-1;
22             std::fill(&ch[sz][0],&ch[sz][S],0);
23             return sz;
24         }
25         int idx(const int &c) const {
26             return c-'a';
27         }
28     public:
29         void reset() {
30             std::fill(&ch[0][0],&ch[0][S],sz=0);
31         }
32         void insert(const char s[],const int &id) {
33             int p=0;
34             for(register int i=0;s[i];i++) {
35                 const int c=idx(s[i]);
36                 p=ch[p][c]?:ch[p][c]=new_node();
37             }
38             val[p]=id;
39         }
40         void get_fail() {
41             for(register int i=0;i<S;i++) {
42                 if(ch[0][i]) q.push(ch[0][i]);
43             }
44             while(!q.empty()) {
45                 const int &x=q.front();
46                 for(register int i=0;i<S;i++) {
47                     int &y=ch[x][i];
48                     if(!y) {
49                         y=ch[fail[x]][i];
50                         continue;
51                     }
52                     fail[y]=ch[fail[x]][i];
53                     q.push(y);
54                 }
55                 q.pop();
56             }
57         }
58         void find(const char s[]) {
59             for(register int i=0,p=0;s[i];i++) {
60                 for(register int j=p=ch[p][idx(s[i])];j;j=fail[j]) {
61                     if(~val[j]) cnt[val[j]]++;
62                 }
63             }
64         }
65 };
66 AhoCorasick ac;
67 int main() {
68     for(int n;(n=getint());) {
69         ac.reset();
70         for(register int i=0;i<n;i++) {
71             cnt[i]=0;
72             scanf("%s",s[i]);
73             ac.insert(s[i],i);
74         }
75         ac.get_fail();
76         scanf("%s",t);
77         ac.find(t);
78         int ans=0;
79         for(register int i=0;i<n;i++) ans=std::max(ans,cnt[i]);
80         printf("%d\n",ans);
81         for(register int i=0;i<n;i++) {
82             if(cnt[i]==ans) puts(s[i]);
83         }
84     }
85     return 0;
86 }

 

posted @ 2018-03-14 20:44  skylee03  阅读(109)  评论(0编辑  收藏  举报