#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<queue>
using namespace std;
typedef struct Trie_Node
{
Trie_Node *fail;
Trie_Node *next[26];
int cnt;
}Trie;
char p[55];
char s[1000000];
void insert_word(char *key, Trie *root)
{
Trie *p = root;
int len = strlen(key);
for(int i = 0; i < len; i++)
{
if(p->next[key[i] - 'a'] == NULL){
Trie *temp = new Trie;
for(int j = 0;j < 26; j++)
temp->next[j] = NULL;
temp->cnt = 0;
temp->fail = NULL;
p->next[key[i] - 'a'] = temp;
}
p = p->next[key[i] - 'a'];
}
p->cnt++;
}
void get_fail(Trie *root)
{
root->fail = NULL;
Trie *p = NULL;
queue<Trie *>Q;
Q.push(root);
while(!Q.empty())
{
Trie *temp = Q.front();
Q.pop();
for(int i = 0; i < 26; i++)
{
if(temp->next[i] != NULL)
{
if(temp == root)
{
temp->next[i]->fail = root;
}
else
{
p = temp->fail;
while(p != NULL)
{
if(p->next[i] != NULL)
{
temp->next[i]->fail = p->next[i];
break;
}
p = p->fail;
}
if(p == NULL) temp->next[i]->fail = root;
}
Q.push(temp->next[i]);
}
}
}
}
int query(Trie *root)
{
int ans = 0;
int len = strlen(s);
Trie *p = root;
for(int i = 0; i < len; i++)
{
int index = s[i] - 'a';
while(p->next[index] == NULL && p != root) p = p->fail;
p = p->next[index];
if(p == NULL)
p = root;
Trie *temp = p;
while(temp != root)
{
ans += temp->cnt;
temp->cnt = 0;
temp = temp->fail;
}
//printf("sdasda\n");
}
//printf("%d\n", ans);
return ans;
}
int main()
{
int t;
scanf("%d", &t);
while(t--)
{
int n;
scanf("%d", &n);
Trie *root = new Trie;
root->cnt = 0;
root->fail = NULL;
for(int i = 0; i < 26; i++)
root->next[i] = NULL;
for(int i = 0; i < n; i++)
{
scanf("%s", p);
insert_word(p, root);
}
get_fail(root);
scanf("%s", s);
//54545printf("sdfadsa\n");
printf("%d\n", query(root));
}
}
ac自动机入门模板
猜你喜欢
转载自blog.csdn.net/weixin_43891021/article/details/97623353
今日推荐
周排行