首先,AC自动机不是Accept自动机,别以为把这段代码复制到OJ上就全都自动AC了……
其实这玩意是Aho-Corasick 造出来的,所以你懂的。
那么这玩意能干嘛咧?
•字符串的匹配问题
•多串的匹配问题※
看不懂吧?解释一下:
例如给几个单词 acbs,asf,dsef,再给出一个 很长的文章,acbsdfgeasf,问在这个文章中,总共出现了多少个单词,或者是单词出现的总次数。
怎么实现的呢,就是KMP+trie树。是以KMP为算法基础,trie为索引结构的东东。那它如何与kmp联系在一起?
•关键是在trie树上加了一种fail指针。
•Fail指针的用途:就像是kmp中的next的数组。
在字符串失配的时候确定转移的节点。AC难点就是指针的算法,看下面这么多图:模板:
1 #include <cstdio> 2 #include <iostream> 3 #include <algorithm> 4 #include <cstring> 5 #include <cmath> 6 #include <queue> 7 #define REP(i, s, n) for(int i = s; i <= n; i ++) 8 #define RAP(i, n, s) for(int i = n; i >= s; i --) 9 #define now ch[x][c] 10 using namespace std; 11 const int maxn = 400000 + 10; 12 const int maxsig = 2; 13 char S[10000 + 10]; 14 int n; 15 inline void read(int &x){ 16 x = 0; int sig = 1; char ch = getchar(); 17 while(!isdigit(ch)) { if(ch == '-') sig = -1; ch = getchar(); } 18 while(isdigit(ch)) x = 10 * x + ch - '0', ch = getchar(); 19 x *= sig; return ; 20 } 21 inline void write(int x){ 22 if(x == 0) { putchar('0'); return; } 23 if(x < 0) putchar('-'), x = -x; 24 int len = 0, buf[20]; 25 while(x) buf[len ++] = x % 10, x /= 10; 26 RAP(i, len - 1, 0) putchar(buf[i] + '0'); return ; 27 } 28 namespace Aho_Corasick{ 29 int ch[maxn][maxsig], val[maxn], f[maxn], last[maxn], len[maxn], ms; 30 void AC_init(){ 31 ms = 0; 32 memset(ch, 0, sizeof(ch)); 33 memset(val, 0, sizeof(val)); 34 memset(f, 0, sizeof(f)); 35 memset(last, 0, sizeof(last)); 36 memset(len, 0, sizeof(len)); 37 return ; 38 } 39 void insert(char* s, int v){ 40 int x = 0, i; 41 for(i = 0; s[i] != '