1. 程式人生 > >AC自動機筆記

AC自動機筆記

empty efi OS ac自動機 namespace IT %s memset amp

AC自動機

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<cmath>
 5 #include<queue>
 6 #define MAX 100001
 7 #define u(n) (n-‘a‘)
 8 using namespace std;
 9 struct ac{
10     int son[26],fail,sum;
11     void init(){
12         memset(son,0
,sizeof(son)); 13 sum=0; 14 } 15 }a[500001]; 16 queue<int>q; 17 int last[500001],ans=0,n,tot=0,len; 18 char st[1000001],sp[10000][51]; 19 void init(){ 20 for(char i=a;i<=z;i++){ 21 if(a[0].son[u(i)]){ 22 q.push(a[0].son[u(i)]); 23 a[a[0].son[u(i)]].fail=0
; 24 } 25 } 26 while(!q.empty()){ 27 for(char i=a;i<=z;i++){ 28 if(a[q.front()].son[u(i)]){ 29 q.push(a[q.front()].son[u(i)]); 30 int now=a[q.front()].fail; 31 while(now&&!a[now].son[u(i)]) now=a[now].fail;
32 if(a[now].son[u(i)]) a[q.back()].fail=a[now].son[u(i)]; 33 else a[q.back()].fail=0; 34 if(a[a[q.back()].fail].sum){ 35 last[q.back()]=a[q.back()].fail; 36 }else{ 37 last[q.back()]=last[a[q.back()].fail]; 38 } 39 } 40 } 41 q.pop(); 42 } 43 } 44 void ins(char st[]){ 45 int s=0; 46 for(int i=0;i<strlen(st);i++){ 47 if(a[s].son[u(st[i])]==0){ 48 a[s].son[u(st[i])]=++tot; 49 a[tot].init(); 50 s=tot; 51 }else{ 52 s=a[s].son[u(st[i])]; 53 } 54 } 55 a[s].sum++; 56 } 57 void inc(int now){ 58 if(a[now].sum){ 59 ans+=a[now].sum; 60 a[now].sum=0; 61 } 62 while(last[now]){ 63 ans+=a[last[now]].sum; 64 a[last[now]].sum=0; 65 now=last[now]; 66 } 67 } 68 void solution(int len){ 69 int now=0; 70 for(int i=0;i<=len;i++){ 71 if(a[now].son[u(st[i])]){ 72 now=a[now].son[u(st[i])]; 73 }else{ 74 while(now&&!a[now].son[u(st[i])]) now=a[now].fail; 75 if(a[now].son[u(st[i])]) now=a[now].son[u(st[i])]; 76 } 77 inc(now); 78 } 79 } 80 int main(){ 81 scanf("%d",&n); 82 a[0].init(); 83 a[0].fail=0; 84 for(int i=1;i<=n;i++){ 85 scanf("%s",sp[i]); 86 ins(sp[i]); 87 } 88 scanf("%s",st); 89 len=strlen(st); 90 init(); 91 solution(len); 92 printf("%d",ans); 93 return 0; 94 }

AC自動機筆記