AC自动机
https://www.luogu.com.cn/problem/P3808
简单版
\(n\) 个模式串和一个文本串,求有多少个不同的模式串在文本串里出现过。
两个模式串不同当且仅当他们编号不同。
#include
using namespace std;
#define LL long long
const int N = 1e6 + 10;
LL n;
char s[N];
struct ACA{
LL trie[N][26], cnt[N], fail[N], idx = 0;
void insert(char s[]){
LL u = 0;
for (int i = 0; s[i]; i ++ ){
LL v = s[i] - 'a';
if (!trie[u][v]) trie[u][v] = ++ idx;
u = trie[u][v];
}
cnt[u] ++ ;
}
void get_fail(){
queue q;
for (int i = 0; i < 26; i ++ )
if (trie[0][i]){
fail[trie[0][i]] = 0;
q.push(trie[0][i]);
}
while (q.size()){
LL u = q.front();
q.pop();
for (int v = 0; v < 26; v ++ ){
if (trie[u][v]){
fail[trie[u][v]] = trie[fail[u]][v];
q.push(trie[u][v]);
}
else trie[u][v] = trie[fail[u]][v];
}
}
}
LL query(char s[]){
LL u = 0, ans = 0;
for (int i = 0; s[i]; i ++ ){
u = trie[u][s[i] - 'a'];
for (LL v = u; v && ~ cnt[v]; v = fail[v]){
ans += cnt[v];
cnt[v] = -1;
}
}
return ans;
}
}aca;
int main(){
cin >> n;
for (int i = 1; i <= n; i ++ ){
cin >> s;
aca.insert(s);
}
aca.get_fail();
cin >> s;
cout << aca.query(s) << "\n";
return 0;
}