听完学长讲,总算是把模板打下来了,慢慢背,慢慢理解
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; #define MAX_N 1000006 #define MAX_Tot 500005 struct Aho{ struct state{ int next[26]; int fail,cnt; }st[MAX_Tot]; int size; queue<int> que; void init(){ while(que.size())que.pop(); for(int i=0;i<MAX_Tot;i++){ memset(st[i].next,0,sizeof(st[i].next)); st[i].fail=st[i].cnt=0; } size=1; } void insert(char *S){ int n=strlen(S); int now=0; for(int i=0;i<n;i++){ char c=S[i]; if(!st[now].next[c-'a'])st[now].next[c-'a']=size++; now=st[now].next[c-'a']; } st[now].cnt++; } void build(){ st[0].fail=-1; que.push(0); while(que.size()){ int u=que.front(); que.pop(); for(int i=0;i<26;i++){ if(st[u].next[i]){ if(u==0)st[st[u].next[i]].fail=0; else { int v=st[u].fail; while(v!=-1){ if(st[v].next[i]){ st[st[u].next[i]].fail=st[v].next[i]; break; } v=st[v].fail; } if(v==-1)st[st[u].next[i]].fail=0; } que.push(st[u].next[i]); } } } } int get(int u){ int res=0; while(u){ res=res+st[u].cnt; st[u].cnt=0; u=st[u].fail; } return res; } int match(char *S){ int n=strlen(S); int res=0,now=0; for(int i=0;i<n;i++){ char c=S[i]; if(st[now].next[c-'a'])now=st[now].next[c-'a']; else { int p=st[now].fail; while(p!=-1&&st[p].next[c-'a']==0)p=st[p].fail; if(p==-1)now=0; else now=st[p].next[c-'a']; } if(st[now].cnt) res=res+get(now); } return res; } }aho; int T; int N; char S[MAX_N]; int main(){ scanf("%d",&T); while(T--){ aho.init(); scanf("%d",&N); for(int i=0;i<N;i++){ scanf("%s",S); aho.insert(S); } aho.build(); scanf("%s",S); printf("%d\n",aho.match(S)); } return 0; }