这里仅以hdu 2222的题目的自动机为模板。
该模板来自于http://www.bilibili.com/video/av6295004/index_2.html
#include<bits/stdc++.h> const int MAX_N = 1e6 + 5; const int MAX_Tot = 500005; ///Trie + KMP的利用 struct Aho{ struct state{ int next[26]; int fail, cnt;//fail指针指向失配点,失配点一般寻找他父亲节点的失配点。 然后cnt就表示出现的次数 }stateTable[MAX_Tot]; int size; std::queue<int> que; void init(){//初始化 for (int i = 0; i < MAX_Tot; i++){ memset(stateTable[i].next, 0, sizeof(stateTable[i].next)); stateTable[i].fail = stateTable[i].cnt = 0; } while (!que.empty()) que.pop(); size = 1; } void insert(char *S){//构建Trie树 int n = strlen(S); int now = 0; for (int i = 0; i < n; i++){ char c = S[i]; if (!stateTable[now].next[c - 'a']) stateTable[now].next[c - 'a'] = size++; now = stateTable[now].next[c - 'a']; } stateTable[now].cnt++; } //构建AC自动机 void build(){//由于构建AC自动机是需要提前知道父亲节点的失配指针的,且其他结点的也需要知道。所以这里用bfs,因为失配指针的长度不可能长于目前长度 stateTable[0].fail = -1;//根节点的是失配指针不存在,所以为-1 que.push(0); while (!que.empty()){ int u = que.front(); que.pop(); for (int i = 0; i < 26; i++){ if (stateTable[u].next[i]){//如果存在子节点的话 if (u == 0) stateTable[stateTable[u].next[i]].fail = 0;//根节点的儿子节点的失配全为0 else { int v = stateTable[u].fail; while (v != -1){ if (stateTable[v].next[i]){//找到失配点 stateTable[stateTable[u].next[i]].fail = stateTable[v].next[i]; break; } v = stateTable[v].fail; } if (v == -1) stateTable[stateTable[u].next[i]].fail = 0;//没有找到失配点,那么就重新从0开始出发 } que.push(stateTable[u].next[i]); } } } } inline int cal(int u){ int res = 0; while (u){ res += stateTable[u].cnt; stateTable[u].cnt = 0;//因为每个串只需要计算一次,所以这里要对cnt进行清空 u = stateTable[u].fail; } return res; } int match(char *S){ int n = strlen(S); int res = 0, now = 0; for (int i = 0; i < n; i++){ char c = S[i]; if (stateTable[now].next[c - 'a'])//如果存在子节点,则继续往下搜 now = stateTable[now].next[c - 'a']; else {//如果不存在,则沿失配边走。 int p = stateTable[now].fail; while (p != -1 && stateTable[p].next[c - 'a'] == 0) p = stateTable[p].fail; if (p == -1) now = 0;//如果没有找到失配点,则另now = 根节点 else now = stateTable[p].next[c - 'a']; } if (stateTable[now].cnt) res += cal(now); } return res; } }aho; char ch[MAX_N];