这个和某谷的AC自动机模板简单版差不多。
但还是要注意几点的:
1.这个是统计出现次数,而不是是否出现,所以在查询的时候加上这个节点的val后,不能把val标记为-1。那么也就可以说查询的时间复杂度能比简单版的稍微第一慢一点。
2.考虑k个一样的模式串:刚开始我想的是每一个节点开一个vector,记录这里是第几个模式串。但其实没有这个必要,对于相同的模式串,我们只用记录任意一个就行,反而在出现次数上要都加上。因为如果主串中存在这些相同的模式串,那么出现次数应该是出现次数 * k。输出的时候如果是这些串最多,那么都应该把这些输出。
1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<cstdlib> 7 #include<cctype> 8 #include<vector> 9 #include<queue> 10 #include<assert.h> 11 #include<ctime> 12 using namespace std; 13 #define enter puts("") 14 #define space putchar(' ') 15 #define Mem(a, x) memset(a, x, sizeof(a)) 16 #define In inline 17 #define forE(i, x, y) for(int i = head[x], y; ~i && (y = e[i].to); i = e[i].nxt) 18 typedef long long ll; 19 typedef double db; 20 const int INF = 0x3f3f3f3f; 21 const db eps = 1e-8; 22 const int maxs = 1e6 + 5; 23 const int maxn = 155; 24 const int maxN = 1.1e4 + 5; 25 In ll read() 26 { 27 ll ans = 0; 28 char ch = getchar(), las = ' '; 29 while(!isdigit(ch)) las = ch, ch = getchar(); 30 while(isdigit(ch)) ans = (ans << 1) + (ans << 3) + ch - '0', ch = getchar(); 31 if(las == '-') ans = -ans; 32 return ans; 33 } 34 In void write(ll x) 35 { 36 if(x < 0) x = -x, putchar('-'); 37 if(x >= 10) write(x / 10); 38 putchar(x % 10 + '0'); 39 } 40 In void MYFILE() 41 { 42 #ifndef mrclr 43 freopen(".in", "r", stdin); 44 freopen(".out", "w", stdout); 45 #endif 46 } 47 48 int n; 49 char s[maxs], s2[maxn][100]; 50 51 int sum[maxn]; 52 int ch[maxN][26], val[maxN], pos[maxN], f[maxN], cnt = 0; 53 In int C(char c) {return c - 'a';} 54 In void Clear(int x) {Mem(ch[x], 0), val[x] = pos[x] = f[x] = 0;} 55 In void insert(int id, char* s) 56 { 57 int len = strlen(s), now = 0; 58 for(int i = 0; i < len; ++i) 59 { 60 int c = C(s[i]); 61 if(!ch[now][c]) Clear(++cnt), ch[now][c] = cnt; 62 now = ch[now][c]; 63 } 64 val[now]++, pos[now] = id; 65 } 66 In void build() 67 { 68 queue<int> q; 69 for(int i = 0; i < 26; ++i) if(ch[0][i]) q.push(ch[0][i]); 70 while(!q.empty()) 71 { 72 int now = q.front(); q.pop(); 73 for(int i = 0; i < 26; ++i) 74 { 75 if(ch[now][i]) f[ch[now][i]] = ch[f[now]][i], q.push(ch[now][i]); 76 else ch[now][i] = ch[f[now]][i]; 77 } 78 } 79 } 80 In void query(char* s) 81 { 82 int len = strlen(s), now = 0; 83 for(int i = 0; i < len; ++i) 84 { 85 int c = C(s[i]); 86 now = ch[now][c]; 87 for(int j = now; j; j = f[j]) sum[pos[j]] += val[j]; 88 } 89 } 90 91 In void init() 92 { 93 Clear(cnt = 0), Mem(sum, 0); 94 } 95 96 int main() 97 { 98 // MYFILE(); 99 while(scanf("%d", &n) && n) 100 { 101 init(); 102 for(int i = 1; i <= n; ++i) 103 { 104 scanf("%s", s2[i]); 105 insert(i, s2[i]); 106 } 107 build(); 108 scanf("%s", s); 109 query(s); 110 int Max = -1; 111 for(int i = 1; i <= n; ++i) Max = max(Max, sum[i]); 112 write(Max), enter; 113 for(int i = 1; i <= n; ++i) if(sum[i] == Max) puts(s2[i]); 114 } 115 return 0; 116 }