AC自动机模板,可重新build
struct AC_automation { int L; int next[maxnode][sigma_size]; int val[maxnode]; int fail[maxnode], last[maxnode]; int newnode() { memset(next[L],0,sizeof(next[L])); fail[L] = last[L] = val[L] = 0; return L++; } //新建结点 void init() { memset(next[0], 0, sizeof(next[0])); fail[0] = last[0] = val[0] = 0; L = 1; }// 初始化 inline int idx(char c) { return c - '0'; } int insert(const char *str) { int len = strlen(str), u = 0; for(int i = 0; i < len; i++) { int c = idx(str[i]); if(next[u][c] == 0) { memset(next[L], 0, sizeof(next[L])); fail[L] = last[L] = val[L] = 0; next[u][c] = L++; } u = next[u][c]; } int ret = val[u]; val[u] = 1; return !ret; }// 插入字典树 bool ask(const char *str) { int len = strlen(str), u = 0; for(int i = 0; i < len; i++) { int c = idx(str[i]); if(next[u][c] == 0) return false; u = next[u][c]; } return val[u]; } // 存不存在 void build() { std::queue<int> q; int u = 0; fail[0] = 0; for(int c = 0; c < sigma_size; c++) { int u = next[0][c]; if(u) { fail[u] = last[u] = 0; q.push(u); } } while(!q.empty()) { int r = q.front(); q.pop(); for(int c = 0; c < sigma_size; c++) { int u = next[r][c]; if(!u) continue; q.push(u); int v = fail[r]; while(v && !next[v][c]) v = fail[v]; fail[u] = next[v][c]; last[u] = val[fail[u]] ? fail[u] : last[fail[u]]; } } }//get-fail void calc(int now, int &ans) { if(now) { ans += val[now]; calc(last[now], ans); } } int query(char *str) { //printf("query %s\n", str); int len = strlen(str), u = 0; int ans = 0; for(int i = 0; i < len; i++) { int c = idx(str[i]); while(u && !next[u][c]) u = fail[u]; u = next[u][c]; if(val[u]) calc(u, ans); else if(last[u]) calc(last[u], ans); } return ans; }// 查询出现次数 }ac1,ac2;