首页 > 代码库 > HDOJ - 2222 [AC自动机]

HDOJ - 2222 [AC自动机]

此题为AC自动机的裸题。

代码如下:

/**************************************Problem : HDOJ - 2222Author : Magician VanMethod : AC-AutomationTime : 07/30/2014**************************************/#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>#include <queue>using namespace std;const int MaxL = 1000000 + 5, SmallL = 50 + 5, MaxKind = 26 + 5, MaxNode = 50 * 10000 + 10;int T, n, Ans, top;char Str[MaxL], Ss[SmallL];typedef struct TrieNode{    int count;    TrieNode *Next[MaxKind], *fail;    void clear()    {        count = 0;        fail = NULL;        for (int i = 0; i <= 25; i++) Next[i] = NULL;    }} Trie;Trie *root, Ta[MaxNode];void Insert(char *S, int len){    Trie *p = root;    int t;    for (int i = 0; i <= len - 1; i++)    {        t = S[i] - a;        if (p -> Next[t] == NULL)        {            Trie *temp = &Ta[++top];            temp -> clear();            p -> Next[t] = temp;        }        p = p -> Next[t];    }    p -> count++;}queue<Trie *> Q;void Build_AC_Automation(){    root -> fail = NULL;    while (!Q.empty()) Q.pop();    Q.push(root);    Trie *now, *p;    while (!Q.empty())    {        now = Q.front();        Q.pop();        for (int i = 0; i <= 25; i++)        {            if (now -> Next[i] == NULL) continue;            if (now == root)            {                now -> Next[i] -> fail = root;            }            else            {                p = now -> fail;                while (p != NULL)                {                    if (p -> Next[i] != NULL)                    {                        now -> Next[i] -> fail = p -> Next[i];                        break;                    }                    p = p -> fail;                }                if (p == NULL) now -> Next[i] -> fail = root;            }            Q.push(now -> Next[i]);        }    }}void Query(char *S, int len){    int t;    Trie *now = root, *temp;    for (int i = 0; i <= len - 1; i++)    {        t = S[i] - a;        while (now != root && now -> Next[t] == NULL) now = now -> fail;        now = now -> Next[t];        if (now == NULL) now = root;        temp = now;        while (temp != NULL && temp -> count != -1)        {            Ans += temp -> count;            temp -> count = -1;            temp = temp -> fail;        }    }}inline void read_int(int &num){    char c; while (c = getchar(), c < 0 || c > 9);    num = c - 0; while (c = getchar(), c >= 0 && c <= 9) num = num * 10 + c - 0;}int main(){    read_int(T);    for (int Case = 1; Case <= T; Case++)    {        Ans = 0;        top = 0;        root = &Ta[++top];        root -> clear();        read_int(n);        for (int i = 1; i <= n; i++)        {            scanf("%s", Ss);            Insert(Ss, strlen(Ss));        }        scanf("%s", Str);        Build_AC_Automation();        Query(Str, strlen(Str));        printf("%d\n", Ans);    }    return 0;}