P3808 【模板】AC自动机(简单版)
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int maxn=1000005; 8 int n,cnt=0,ans=0; 9 struct nod{ 10 int ne[27]; 11 int fail,num,flag; 12 bool vis; 13 }; 14 nod tri[maxn]; 15 inline void ins(string s){ 16 int pos=0; 17 for(register int i=0;i<(int)s.size();i++){ 18 int c=s[i]-'a'; 19 if(tri[pos].ne[c])pos=tri[pos].ne[c]; 20 else pos=tri[pos].ne[c]=++cnt; 21 tri[pos].num++; 22 } 23 tri[pos].flag++; 24 } 25 inline void get(int start,int now,int num){ 26 if(!now)return; 27 if(tri[tri[now].fail].ne[num]){ 28 tri[start].fail=tri[tri[now].fail].ne[num]; 29 return; 30 } 31 else get(start,tri[now].fail,num); 32 } 33 inline void build(){ 34 queue<int>q; 35 for(register int i=0;i<26;i++){ 36 if(tri[0].ne[i]){ 37 q.push(tri[0].ne[i]); 38 tri[0].fail=0; 39 } 40 } 41 while(!q.empty()){ 42 int now=q.front(); 43 q.pop(); 44 for(register int i=0;i<26;i++){ 45 if(tri[now].ne[i]){ 46 get(tri[now].ne[i],now,i); 47 q.push(tri[now].ne[i]); 48 } 49 } 50 } 51 } 52 inline void AC(string s){ 53 int pos=0,post=0; 54 while(pos<=(int)s.size()){ 55 if(tri[post].vis==0&&tri[post].flag!=0){ 56 tri[post].vis=1; 57 ans+=tri[post].flag; 58 } 59 if(pos==(int)s.size())return; 60 int c=s[pos]-'a'; 61 if(!tri[post].ne[c]){ 62 post=tri[post].fail; 63 if(!post){ 64 pos++; 65 continue; 66 } 67 } 68 else { 69 post=tri[post].ne[c]; 70 pos++; 71 } 72 } 73 } 74 int main(){ 75 std::ios::sync_with_stdio(false); 76 cin>>n; 77 string tmp; 78 for(register int i=1;i<=n;i++){ 79 cin>>tmp; 80 ins(tmp); 81 } 82 build(); 83 cin>>tmp; 84 AC(tmp); 85 cout<<ans<<endl; 86 }