HDOJ 3065 病毒侵袭持续中(AC自动机入门)

思路:

AC自动机,单词统计。

 

#include <iostream>

#include <deque>

using namespace std;



const int MAX_NODE = 1000 * 50 + 10;

const int CHILD_NUM = 26;



char virus[1010][56];

int num[1010];



class AcAutomaton 

{

private:

    int size;

    int trie[MAX_NODE][CHILD_NUM];

    int value[MAX_NODE];

    int fail[MAX_NODE];

    int table[128];



public:

    void Initialize()

    {

        fail[0] = 0;

        memset(table, -1, sizeof(table));

        for (int i = 0; i < 26; ++i)

            table['A' + i] = i;

    }



    void Reset()

    {

        size = 1;

        memset(trie[0], 0, sizeof(trie[0]));

        memset(fail, 0, sizeof(fail));

        memset(value, 0, sizeof(value));

    }



    void Insert(char* word, int key)

    {

        int p = 0;

        for (int i = 0; word[i]; ++i)

        {

            int m = table[word[i]];

            if (!trie[p][m])

            {

                memset(trie[size], 0, sizeof(trie[0]));

                trie[p][m] = size++;

            }

            p = trie[p][m];

        }

        value[p] = key;

    }



    void Construct()

    {

        deque<int> deq;



        for (int i = 0; i < CHILD_NUM; ++i)

            if (trie[0][i])

            {

                fail[trie[0][i]] = 0;

                deq.push_back(trie[0][i]);

            }



        while (!deq.empty())

        {

            int u = deq.front();

            deq.pop_front();

            for (int i = 0; i < CHILD_NUM; ++i)

            {

                int& v = trie[u][i];

                if (v)

                {

                    fail[v] = trie[fail[u]][i];

                    deq.push_back(v);

                }

                else

                    v = trie[fail[u]][i];

            }

        }

    }



    void Work(char* word, int arr[])

    {

        int p = 0;

        for (int i = 0; word[i]; ++i)

        {

            int m = table[word[i]]; 

            if (m == -1) 

            {

                p = 0; continue;

            }

            int t = p = trie[p][m];

            while (value[t])

            {

                ++arr[value[t]];

                t = fail[t];

            }

        }

    }

};



AcAutomaton Ac;

char word[2000010];



int main()

{

    int n;

    Ac.Initialize();

    while (~scanf("%d", &n))

    {

        Ac.Reset();



        for (int i = 1; i <= n; ++i)

        {

            scanf("%s", virus[i]);

            Ac.Insert(virus[i], i);

        }

        Ac.Construct();



        scanf("%s", word);

        memset(num, 0, sizeof(num));

        Ac.Work(word, num);



        for (int i = 1; i <= n; ++i)

            if (num[i])

                printf("%s: %d\n", virus[i], num[i]);

    }

    return 0;

}

你可能感兴趣的:(AC自动机)