HDU 2222 Keywords Search(AC自动机)

传送门
AC自动机入门好题。作为模板的检测题吧。
AC自动机构造方法:
插入模式串,建成Trie,如果对于某个点x的next[c]不存在的话,就把next[c]指向fail[x]的next[c]
在Trie上加入失配边,就成功啦。
查找的时候一直按着next信息走到下一个节点。
代码:

#include<stdio.h>
#include<cstring>
#define MAXN 1000005
#define MAXC 26
#define MAXM 10005
#define MAXL 55
int n, root, sz, q[MAXM*MAXL];
char s[MAXN];
struct Trie {
    int nxt[MAXC], fail, ed;
} t[MAXM * MAXL];
int NewNode() {
    ++ sz;
    memset(t[sz].nxt, 0, sizeof t[sz].nxt);
    t[sz].ed = 0;
    return sz;
}
void Ins(char *s) {
    int len = strlen(s), cur = root;
    for(int i = 0; i < len; ++ i) {
        if(!t[cur].nxt[s[i]-'a']) t[cur].nxt[s[i]-'a'] = NewNode();
        cur = t[cur].nxt[s[i]-'a'];
    }
    ++ t[cur].ed;
}
void Build() {
    int l = 1, r = 0; t[root].ed = -1;
    for(int i = 0; i < MAXC; ++ i)
        if(!t[root].nxt[i]) t[root].nxt[i] = root;
        else {
            t[ t[root].nxt[i] ].fail = root;
            q[++ r] = t[root].nxt[i];
        }
    while(l <= r) {
        int u = q[l ++];
        for(int i = 0; i < MAXC; ++ i)
            if(!t[u].nxt[i]) t[u].nxt[i] = t[ t[u].fail ].nxt[i];
            else {
                t[ t[u].nxt[i] ].fail = t[ t[u].fail ].nxt[i];
                q[++ r] = t[u].nxt[i];
            }
    }
}
int Query(char *s) {
    int len = strlen(s), cur = root, ans = 0;
    for(int i = 0; i < len; ++ i) {
        cur = t[cur].nxt[s[i]-'a'];
        int tmp = cur;
        while(~t[tmp].ed) {
            ans += t[tmp].ed;
            t[tmp].ed = -1;
            tmp = t[tmp].fail;
        }
    }
    return ans;
}
int main() {
    int T;
    scanf("%d", &T);
    while(T --) {
        sz = 0; root = NewNode();
        scanf("%d", &n);
        for(int i = 1; i <= n; ++ i) {
            scanf("%s", s);
            Ins(s);
        }
        Build();
        scanf("%s", s);
        printf("%d\n", Query(s));
    }
    return 0;
}

你可能感兴趣的:(HDU 2222 Keywords Search(AC自动机))