https://www.luogu.org/problemnew/show/3808
在Tire上做KMP
#include<cstdio> #include<queue> #include<iostream> #define FOR(i,s,t) for(register int i=s;i<=t;++i) using std::cin; const int N=4000011; char s[N]; int tot,n,ans; namespace AC_automaton{ struct Tire{ int cnt,fail; int to[27]; }tr[N]; inline void build_tire(){ int u=0; for(register int i=0;s[i]!=‘\0‘;++i){ if(!tr[u].to[s[i]-‘a‘]) tr[u].to[s[i]-‘a‘]=++tot; u=tr[u].to[s[i]-‘a‘]; } ++tr[u].cnt; } inline void build_automaton(){ int v,u; std::queue<int>q; FOR(i,0,25) if((v=tr[0].to[i])) q.push(v); int now; while(!q.empty()){ now=q.front();q.pop(); FOR(i,0,25){ v=tr[now].to[i]; u=tr[now].fail; if(v){ tr[v].fail=tr[u].to[i]; q.push(v); } else tr[now].to[i]=tr[u].to[i]; } } } inline void match(){ int now=0,tmp; for(register int i=0;s[i]!=‘\0‘;++i){ now=tr[now].to[s[i]-‘a‘]; tmp=now; while(tmp&&tr[tmp].cnt!=-1){ ans+=tr[tmp].cnt; tr[tmp].cnt=-1; tmp=tr[tmp].fail; } } } } using namespace AC_automaton; int main(){ scanf("%d\n",&n); while(n--){ scanf("%s",s); build_tire(); } tr[0].fail=0; build_automaton(); scanf("%s",s); match(); printf("%d\n",ans); return 0; }