HDU 6096 AC自动机
题解: 主要的思路就是怎么能让这两个串链接起来,还有就是明白AC自动机主要处理什么问题,知道了这些这个问题就能很好的解决了。。
#include<bits/stdc++.h> #define ll long long #define inf 0x3f3f3f3f using namespace std; typedef pair<int,int> P; const int MAXN = 2000010; int pos[MAXN]; struct Trie{ int next[MAXN][27], fail[MAXN], LEN[MAXN], ans[MAXN]; int root, L; int insert(char buf[]) { int len = strlen(buf), now = 0; for(int i = 0; i < len; i++) { if(next[now][buf[i] - 'a'] == 0) { next[now][buf[i] - 'a'] = ++L; LEN[L] = i + 1; } now = next[now][buf[i] - 'a']; } return now; } void init()//不要忘记初始化 { memset(next, 0, sizeof(int) * (L + 1) * 27); memset(fail, 0, sizeof(int) * (L + 1)); memset(LEN, 0, sizeof(int) * (L + 1)); memset(ans, 0, sizeof(int) * (L + 1)); root = L = 0; } void build() { queue<int>q; fail[root] = root; for(int i = 0; i < 27; i++) if(next[root][i] == 0) next[root][i] = root; else { fail[next[root][i]] = root; q.push(next[root][i]); } while(!q.empty()) { int now = q.front(); q.pop(); for(int i = 0; i < 27; i++) if(next[now][i] == 0) next[now][i] = next[fail[now]][i]; else { fail[next[now][i]] = next[fail[now]][i]; q.push(next[now][i]); } } } void query(char buf[], int len) { int now = root; for(int i = 0; buf[i]; i++) { now = next[now][buf[i] - 'a']; int tmp = now; while(tmp != root) { if(LEN[tmp] <= len) ans[tmp]++; tmp = fail[tmp]; } } } }AC; char str[MAXN]; char *s[100010]; int len[100010]; char s1[100010], s2[100010]; int main() { int T, n, q; scanf("%d", &T); while(T--) { AC.init(); scanf("%d %d", &n, &q); int cnt = 0; for(int i = 0; i < n; i++) { s[i] = str + cnt; scanf("%s", s[i]); len[i] = strlen(s[i]) + 1; cnt += len[i]; strcpy(str + cnt, s[i]); str[cnt - 1] = 'z' + 1; cnt += len[i]; } for(int i = 0; i < q; i++) { s1[0] = 'z' + 1; scanf("%s%s", s1 + 1, s2); strcat(s2, s1); pos[i] = AC.insert(s2); } AC.build(); for(int i = 0; i < n; i++) AC.query(s[i], len[i]); for(int i = 0; i < q; i++) printf("%d\n", AC.ans[pos[i]]); } return 0; }