AC自动机总结

· · 题解

【算法目标】

【算法思路】

【参考程序】

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

char st[1000005],p[1000005];
struct TRIE{
    int son[27];
    int val;
}trie[1000005];
int fail[1000005];
int L;

void Fill_in(char *st,int rank)
{
    int len=strlen(st),u=0;
    for (int i=0;i<len;i++)
    {
        int v=st[i]-'a';
        if (!trie[u].son[v])
            trie[u].son[v]=++L;
        u=trie[u].son[v];
    }
    trie[u].val++;
}
void Build()
{
    queue <int> q;
    for (int i=0;i<26;i++)
        if (trie[0].son[i])
        {
            q.push(trie[0].son[i]);
            fail[trie[0].son[i]]=0;
        }
    while (!q.empty())
    {
        int now=q.front();q.pop();
        for (int i=0;i<26;i++)
            if (trie[now].son[i])
            {
                fail[trie[now].son[i]]=trie[fail[now]].son[i];
                q.push(trie[now].son[i]);
            }else
            trie[now].son[i]=trie[fail[now]].son[i];
    }
}
int Check(char *st)
{
    int len=strlen(st),u=0,ans=0;
    for (int i=0;i<len;i++)
    {
        u=trie[u].son[st[i]-'a'];
        for (int h=u;h&&~trie[h].val;h=fail[h])
        {
            ans+=trie[h].val;
            trie[h].val=-1;
        }
    }
    return ans;
}
int main()
{
    int T,n;
    scanf("%d",&n);
    for (int i=1;i<=n;i++)
    {
        scanf("%s",st);
        Fill_in(st,i);
    }
    Build();
    scanf("%s",p);
    printf("%d",Check(p));
    return 0;
}