分析:
建立AC自动机,然后在文本串扫一遍,统计每个串出现的次数。
代码:
换了种写法
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 500100; char str[N << 1], s[110]; int ch[N][26], fail[N], val[N], last[N], q[N], L, R, Index; void Insert(char *s) { int len = strlen(s), u = 0; for (int i=0; i<len; ++i) { int c = s[i] - 'a'; if (!ch[u][c]) ch[u][c] = ++Index; u = ch[u][c]; } val[u] ++; } void build() { L = 1;R = 0; fail[0] = 0; for (int c=0; c<26; ++c) { int u = ch[0][c]; if (u) fail[u] = 0, q[++R] = u, last[u] = 0; } while (L <= R) { int u = q[L++]; for (int c=0; c<26; ++c) { int v = ch[u][c]; if (!v) ch[u][c] = ch[fail[u]][c]; else { q[++R] = v; fail[v] = ch[fail[u]][c]; last[v] = val[fail[v]] ? fail[v] : last[fail[v]]; } } } } int find(char *s) { int Ans = 0, u = 0, len = strlen(s); for (int i=0; i<len; ++i) { int c = s[i] - 'a'; u = ch[u][c]; if (val[u]) Ans += val[u], val[u] = 0; int p = u; while (last[p]) { p = last[p]; if (val[p]) Ans += val[p], val[p] = 0; } } return Ans; } int main () { int n; scanf("%d", &n); while (n--) { scanf("%s", s); Insert(s); } build(); scanf("%s",str); printf("%d ",find(str)); return 0; }
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int N = 500100; char str[N << 1], s[110]; int ch[N][26], fail[N], val[N], last[N], q[N], L, R, Index; void Insert(char *s) { int len = strlen(s), u = 0; for (int i=0; i<len; ++i) { int c = s[i] - 'a'; if (!ch[u][c]) ch[u][c] = ++Index; u = ch[u][c]; } val[u] ++; } void build() { L = 1;R = 0; fail[0] = 0; for (int c=0; c<26; ++c) { int u = ch[0][c]; if (u) fail[u] = 0, q[++R] = u, last[u] = 0; } while (L <= R) { int u = q[L++]; for (int c=0; c<26; ++c) { int v = ch[u][c]; if (!v) { ch[u][c] = ch[fail[u]][c]; continue; } q[++R] = v; int p = fail[u]; while (p && !ch[p][c]) p = fail[p]; fail[v] = ch[p][c]; last[v] = val[fail[v]] ? fail[v] : last[fail[v]]; } } } int find(char *s) { int Ans = 0, u = 0, len = strlen(s); for (int i=0; i<len; ++i) { int c = s[i] - 'a'; u = ch[u][c]; if (val[u]) Ans += val[u], val[u] = 0; int p = u; while (last[p]) { p = last[p]; if (val[p]) Ans += val[p], val[p] = 0; } } return Ans; } int main () { int n; scanf("%d", &n); while (n--) { scanf("%s", s); Insert(s); } build(); scanf("%s",str); printf("%d ",find(str)); return 0; }