AC自动机
study from :https://pan.baidu.com/s/1Igr_1EgL5FtB-zpRKosToQ (别人的ppt,如有侵权,请告知我)
没必要初始化
如果所有的变量初始值为0/NULL
如果是多组数据,每次根节点和辅助节点重新创建!
fail 长度比之间小
指针 很多个链组成,一个节点,只指向有且只有一个节点;而一个节点,有可能被多个节点指向。同时也是拓扑结构。
每次bfs搜索:最大代码 点数*26('a'-'z') 链式结构
可以利用之前的搜索结果
https://www.luogu.org/problemnew/show/P3808
1 /* 2 模式串出现的总次数 3 */ 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cmath> 7 #include <cstring> 8 #include <string> 9 #include <algorithm> 10 #include <iostream> 11 using namespace std; 12 #define ll long long 13 14 const double eps=1e-8; 15 const ll inf=1e9; 16 const ll mod=1e9+7; 17 const int maxn=1e6+10; 18 19 struct node 20 { 21 int g,cond; 22 node *nex[26],*fail,*pre; 23 }*tr,*be,*p,*pos,*td; 24 25 node *q[maxn]; 26 char str[maxn]; 27 28 int main() 29 { 30 int n,len,i,head,tail,d,sum=0; 31 tr=new node(); 32 be=new node(); 33 tr->pre=be; 34 tr->fail=be; 35 be->fail=be; 36 for (i=0;i<26;i++) 37 be->nex[i]=tr; 38 39 scanf("%d",&n); 40 while (n--) 41 { 42 scanf("%s",str); 43 pos=tr; 44 len=strlen(str); 45 for (i=0;i<len;i++) 46 { 47 d=str[i]-97; 48 if (!pos->nex[d]) 49 { 50 p=new node(); 51 pos->nex[d]=p; 52 p->pre=pos; 53 } 54 pos=pos->nex[d]; 55 } 56 pos->g++; 57 } 58 59 head=0,tail=1; 60 q[1]=tr; 61 while (head<tail) 62 { 63 head++; 64 td=q[head]; 65 for (i=0;i<26;i++) 66 if (td->nex[i]) 67 { 68 q[++tail]=td->nex[i]; 69 pos=td->fail; 70 while (!pos->nex[i]) 71 pos=pos->fail; 72 td->nex[i]->fail=pos->nex[i]; 73 } 74 } 75 76 scanf("%s",str); 77 len=strlen(str); 78 pos=tr; 79 for (i=0;i<len;i++) 80 { 81 d=str[i]-97; 82 while (!pos->nex[d]) 83 pos=pos->fail; 84 pos=pos->nex[d]; 85 86 p=pos; 87 while (!p->cond) 88 { 89 sum+=p->g; 90 p->cond=1; 91 p=p->fail; 92 } 93 } 94 printf("%d",sum); 95 return 0; 96 } 97 /* 98 2 99 b 100 a 101 abcd 102 103 2 104 ab 105 ac 106 abc 107 108 2 109 ababc 110 abc 111 ababc 112 113 3 114 ab 115 abc 116 abca 117 ababc 118 119 6 120 ab 121 abc 122 abc 123 abc 124 abab 125 ababc 126 ababc 127 */
https://www.luogu.org/problemnew/show/P3796
1 /* 2 一个模式串出现的最大次数 3 */ 4 #include <cstdio> 5 #include <cstdlib> 6 #include <cmath> 7 #include <cstring> 8 #include <string> 9 #include <algorithm> 10 #include <iostream> 11 using namespace std; 12 #define ll long long 13 14 const double eps=1e-8; 15 const ll inf=1e9; 16 const ll mod=1e9+7; 17 const int maxn=1e6+10; 18 19 struct node 20 { 21 // char c; 22 int g,hav; 23 node *nex[26],*pre,*fail; 24 }*tr,*be,*p,*pos,*q[maxn],*td; 25 26 int maxg=1,cnt_g,num[150+10]; 27 28 char str[maxn],s[150+10][70+10]; 29 30 int main() 31 { 32 int n,len,i,j,d,head,tail,N; 33 34 while (1) 35 { 36 scanf("%d",&n); 37 if (n==0) 38 break; 39 40 ///init 41 tr=new node(); 42 be=new node(); 43 tr->pre=be; 44 tr->fail=be; 45 be->fail=be; 46 for (i=0;i<26;i++) 47 be->nex[i]=tr; 48 maxg=1; 49 50 for (N=1;N<=n;N++) 51 { 52 scanf("%s",str); 53 strcpy(s[N],str); 54 55 len=strlen(str); 56 pos=tr; 57 for (i=0;i<len;i++) 58 { 59 d=str[i]-97; 60 if (!pos->nex[d]) 61 { 62 p=new node(); 63 pos->nex[d]=p; 64 p->pre=pos; 65 // p->c=d; 66 } 67 pos=pos->nex[d]; 68 } 69 pos->hav=N; 70 } 71 72 head=0,tail=1; 73 q[1]=tr; 74 while (head<tail) 75 { 76 head++; 77 td=q[head]; 78 for (d=0;d<26;d++) 79 if (td->nex[d]) 80 { 81 pos=td->fail; 82 while (!pos->nex[d]) 83 pos=pos->fail; 84 td->nex[d]->fail=pos->nex[d]; 85 q[++tail]=td->nex[d]; 86 } 87 } 88 89 scanf("%s",str); 90 len=strlen(str); 91 pos=tr; 92 for (i=0;i<len;i++) 93 { 94 d=str[i]-97; 95 while (!pos->nex[d]) 96 pos=pos->fail; 97 pos=pos->nex[d]; 98 pos->g++; 99 } 100 101 for (i=tail;i>=1;i--) 102 { 103 pos=q[i]; 104 if (pos->hav) 105 { 106 if (maxg<=pos->g) 107 { 108 if (maxg<pos->g) 109 { 110 maxg=pos->g; 111 cnt_g=1; 112 } 113 else 114 cnt_g++; 115 116 num[cnt_g]=pos->hav; 117 118 // j=0; 119 // p=pos; 120 // while (p!=tr) 121 // { 122 // s[cnt_g][j++]=p->c+97; 123 // p=p->pre; 124 // } 125 // s[cnt_g][j]=0; 126 // reverse(s[cnt_g],s[cnt_g]+j); 127 } 128 } 129 pos->fail->g+=pos->g; 130 } 131 132 sort(num+1,num+cnt_g+1); 133 printf("%d\n",maxg); 134 for (i=1;i<=cnt_g;i++) 135 printf("%s\n",s[num[i]]); 136 // printf("%s\n",s[i]); 137 138 ///free pointer 139 } 140 return 0; 141 } 142 /* 143 2 144 cab 145 ab 146 cabcabcab 147 */