【AC自动机】

版权声明:本博客主要用于记录思考过程,方便复习,欢迎留言交流讨论~ https://blog.csdn.net/Floraqiu/article/details/82464505

模板
以HDU 2222为例

#include <bits/stdc++.h>

using namespace std;
const int Max_Tot = 5e5 + 5;

struct Aho
{
    struct state
    {
        int next[26];
        int fail, cnt;
    } table[Max_Tot];

    int sz;

    void Init()
    {
        for(int i = 0; i < Max_Tot; ++i)
        {
            memset(table[i].next, 0, sizeof(table[i].next));
            table[i].fail = table[i].cnt = 0;
        }
        sz = 1;
    }

    void Insert(char* S)
    {
        int n = strlen(S);
        int now = 0;
        for(int i = 0; i < n; ++i)
        {
            int c = S[i] - 'a';
            if(!table[now].next[c])
                table[now].next[c] = sz++;
            now = table[now].next[c];
        }
        table[now].cnt++;
    }

    queue<int> q;

    void Build()
    {
        table[0].fail = -1;
        q.push(0);

        while(q.size())
        {
            int u = q.front();
            q.pop();
            for(int i = 0; i < 26; ++i)
            {
                if(table[u].next[i])
                {
                    if(u == 0)
                        table[table[u].next[i]].fail = 0;
                    else
                    {
                        int v = table[u].fail;
                        while(v != -1)
                        {
                            if(table[v].next[i])
                            {
                                table[table[u].next[i]].fail = table[v].next[i];
                                break;
                            }
                            v = table[v].fail;
                        }
                        if(v == -1) table[table[u].next[i]].fail = 0;
                    }
                    q.push(table[u].next[i]);
                }
            }
        }
    }

    int Get(int u)
    {
        int res = 0;
        while(u)
        {
            res = res + table[u].cnt;
            table[u].cnt = 0;
            u = table[u].fail;
        }
        return res;
    }

    int Match(char* S)
    {
        int n = strlen(S);
        int res = 0, now = 0;
        for(int i = 0; i < n; i++)
        {
            int c = S[i] - 'a';
            if(table[now].next[c])
                now = table[now].next[c];
            else
            {
                int p = table[now].fail;
                while(p != -1 && table[p].next[c] == 0)
                    p = table[p].fail;
                if(p == -1) now = 0;
                else now = table[p].next[c];
            }
            if(table[now].cnt)
                res += Get(now);
        }
        return res;
    }
}aho;

int main()
{
    int t;
    scanf("%d", &t);
    while(t--)
    {
        aho.Init();
        int n;
        scanf("%d", &n);
        char S[1000005];
        while(n--)
        {
            scanf("%s", S);
            aho.Insert(S);
        }
        aho.Build();
        scanf("%s", S);
        printf("%d\n", aho.Match(S));
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Floraqiu/article/details/82464505
今日推荐