AC自动机模板
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdlib>
const int kind=26;
using namespace std;
char b[51],a[1000001]; //a模式串,b为匹配串
struct trie{
struct trie * fail,*next[kind];
int count;
trie(){
fail=NULL;
count=0;
memset(next,NULL,sizeof(next));
}
};
struct trie * root;
void insert(char* str){
int len=strlen(str),i,tem;
struct trie *p,*q;
p=root;
for(i=0;i<len;i++){
tem=str[i]-'a';
if(p->next[tem]==NULL){
q=(struct trie*)calloc(1,sizeof(struct trie));
q->count=0;
q->fail=NULL;
memset(q->next,NULL,sizeof(q->next));
p->next[tem]=q;
}
p=p->next[tem];
}
p->count+=1; //这个题有重复的模式串
}
void buildac(){
int i;
struct trie *p,*tem;
queue<struct trie *>q;
root->fail=NULL;
q.push(root);
while(!q.empty()){
tem=q.front();
q.pop();
for(i=0;i<26;i++){
if(tem->next[i]!=NULL){
if(tem==root)
tem->next[i]->fail=root;
else{
p=tem->fail;
while(p!=NULL){
if(p->next[i]!=NULL){
tem->next[i]->fail=p->next[i];
break;
}
p=p->fail;
}
if(p==NULL)
tem->next[i]->fail=root;
}
q.push(tem->next[i]);
}
}
}
}
int query(char *str){
int len=strlen(str),i,tem,result=0;
struct trie* tmp=root,*p;
for(i=0;i<len;i++){
tem=str[i]-'a';
while(tmp->next[tem]==NULL && tmp!=root)
tmp=tmp->fail;
tmp=tmp->next[tem];
if(tmp==NULL)
tmp=root;
p=tmp;
while(p!=root){ //每到一个位置就加上p->count,以及以他的后缀为前缀的单词
result+=p->count;
p->count=0;
p=p->fail;
}
}
return result;
}
int main(){
int t,T,n,i,j;
scanf("%d",&T);
for(t=1;t<=T;t++){
root=(struct trie*)calloc(1,sizeof(struct trie));
root->fail=NULL;
root->count=0;
memset(root->next,NULL,sizeof(root->next));
scanf("%d",&n);
for(i=1;i<=n;i++){
scanf("%s",b);
insert(b);
}
buildac();
scanf("%s",a);
printf("%d\n",query(a));
}
}
trie图形式
#include <cstdio>
#include <cstring>
#include <queue>
#define N 600000
using namespace std;
char s[1001000];
int next[N][26],fail[N],flag[N],vis[N],pos;
int ans;
int newnode(){
memset(next[pos],0,sizeof(next[pos]));
fail[pos]=flag[pos]=vis[pos]=0;
return pos++;
}
void insert(char * s,int id){
int p=0,i=0;
for(;s[i];i++){
int k=s[i]-'a';
p=next[p][k]?next[p][k]:next[p][k]=newnode();
}
flag[p]++;
}
void makefail(){
queue<int>q;
q.push(0);
while(!q.empty()){
int u=q.front();
q.pop();
for(int i=0;i<26;i++){
int v=next[u][i];
if(v==0)next[u][i]=next[fail[u]][i];
else q.push(v);
if(v && u) fail[v]=next[fail[u]][i];
}
}
}
void findstr(char * s){
int p=0,i;
for(i=0;s[i];i++){
int k=s[i]-'a';
p=next[p][k];
for(int j=p;j && !vis[j];j=fail[j]){
ans+=flag[j];
vis[j]=1;
}
}
}
int main(){
int t,T,n,i,j;
scanf("%d",&T);
for(t=1;t<=T;t++){
scanf("%d",&n);
pos=0;newnode();
for(i=1;i<=n;i++){
scanf("%s",s);
insert(s,i);
}
makefail();
scanf("%s",s);
ans=0;
findstr(s);
printf("%d\n",ans);
}
return 0;
}