这个题是AC自动机的模板题,尽情的享受吧
愿有一天能有人写出自动AC机,让我们无尽的AC吧
#include <iostream>
#include <string>
#include <memory.h>
#include <cstdio>
using namespace std;
const int M = 500010;
const int N = 1000010;
const int MAX_N = 26;
struct TrieNode
{
TrieNode * next;
TrieNode * son[MAX_N];
bool end;
int cnt;
TrieNode()
{
next = NULL;
memset(son,0,sizeof(son));
end = false;
cnt = 0;
}
} *queue[M],*root;
int n;
char str[N];
void INIT();
void TrieInsert(char *);
void Build_AC_Automachine();
int AC_Search();
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
INIT();
Build_AC_Automachine();
scanf("%s",&str);
printf("%d\n",AC_Search());
}
return 0;
}
void INIT()
{
char buf[100];
root = new TrieNode();
scanf("%d",&n);
for(int i = 0;i < n;i++)
{
scanf("%s",&buf);
TrieInsert(buf);
}
return;
}
void TrieInsert(char *buf)
{
int v,pts;
pts = 0;
TrieNode *ptt = root;
while(buf[pts])
{
v = buf[pts] - 'a';
if(ptt->son[v] == NULL)ptt->son[v] = new TrieNode();
ptt = ptt->son[v];
pts++;
}
ptt->end = true;
ptt->cnt++;
return;
}
void Build_AC_Automachine()
{
int top;
top = 0;
queue[top++] = root;
root->next = NULL;
for(int i = 0;i < top;i++)
{
TrieNode *cur = queue[i];
for(int j = 0;j < 26;j++) if(cur->son[j]!=NULL)
{
if(cur == root)cur->son[j]->next = root;
else
{
TrieNode *ptt = cur->next;
while(ptt!= NULL)
{
if(ptt->son[j]!=NULL)
{
cur->son[j]->next = ptt->son[j];
if(ptt->son[j]->end == true)cur->son[j]->end = true;
break;
}
ptt = ptt->next;
}
if(ptt == NULL)cur->son[j]->next = root;
}
queue[top++] = cur->son[j];
}
}
return;
}
int AC_Search()
{
int pts,ans;
pts = ans = 0;
TrieNode *ptt = root;
while(str[pts])
{
int v = str[pts] - 'a';
while(ptt->son[v] == NULL && ptt != root)ptt = ptt->next;
ptt = ptt->son[v];
if(ptt == NULL)ptt = root;
TrieNode *tmp = ptt;
while(tmp != NULL && tmp->cnt != -1)
{
ans += tmp->cnt;
tmp->cnt = -1;
tmp = tmp->next;
}
/*如果计算次数的话
while(tmp != NULL)
{
ans+= tmp->cnt;
tmp = tmp->next;
}*/
pts++;
}
return ans;
}