AC自动机模板
#include <bits/stdc++.h> #define ll long long #define eps 1e-7 using namespace std; inline int read(){ int x=0;int f=1;char ch=getchar(); while(ch>'9'||ch<'0') {if(ch=='-') f=-1;ch=getchar();} while(ch<='9'&&ch>='0') {x=x*10+ch-'0';ch=getchar();} return x*f; } const int MAXN=1e+10; struct node { int endflag; int value; int linkk[26]; int fail; }tree[500010]; int root=0; int slen; char str[1000100]; int q[1000010]; int len,n; void buildtrie(int x,int node){ int s=str[x]-'a'; if(!tree[node].linkk[s]){ tree[node].linkk[s]=++len; tree[len].endflag=0; tree[len].fail=root; } int nextnode=tree[node].linkk[s]; if(x==slen-1){ tree[nextnode].endflag++; return ; } buildtrie(x+1,nextnode); } void init(){ cin>>n; memset(tree,0,sizeof(tree)); for(int i=1;i<=n;i++){ scanf("%s",str); slen=strlen(str); buildtrie(0,root); } } void buildac(){ int head=0; int tail=0; q[++tail]=root; while(head<tail){ int now=q[++head]; for(int i=0;i<26;i++){ if(tree[now].linkk[i]){ int nextnode=tree[now].linkk[i]; if(now!=root){ int temp=tree[now].fail; while(temp!=root&&!tree[temp].linkk[i]){ temp=tree[temp].fail; } tree[nextnode].fail=tree[temp].linkk[i]; } q[++tail]=nextnode; } } } } void find(){ int ans=0; scanf("%s",str); int len=strlen(str); int now=root; for(int i=0;i<len;i++){ int chindex=str[i]-'a'; while(!tree[now].linkk[chindex]&&now!=root){ now=tree[now].fail; } now=tree[now].linkk[chindex]; int temp=now; while(temp!=root&&tree[temp].endflag>-1){ ans+=tree[temp].endflag; tree[temp].endflag=-1; temp=tree[temp].fail; } } cout<<ans<<endl; } int main(){ init(); buildac(); find(); return 0; }