hdu 2222 AC自动机模板(非指针)

题意:给一串字符串再给一个字符串,求前面那些串有多少出现在这个串中。n<=10000,sumlen<=1000000.
PS:好久没打AC自动机了,打一发模板练练手,不过相当讨厌c艹的指针,看着就恶心。。
代码:

#include
#include
#include
#include
#include
#include
#define fo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=5e5+5;
int n,len,trie[maxn][26],fail[maxn],out[maxn],tot,cnt;
char ch[60],s[1000005];
queue <int>q;
void insert(int x,int y)
{
    if(y==len)
    {
        out[x]++;
        return;
    }
    int w=ch[y]-'a';
    if (!trie[x][w])trie[x][w]=++cnt;
    insert(trie[x][w],y+1);
}
void getfail()
{
    fo(i,0,25)if (trie[0][i])q.push(trie[0][i]);
    while (!q.empty())
    {
        int r=q.front();
        q.pop();
        fo(i,0,25)
        if (trie[r][i])
        {
            int u=trie[r][i],v=fail[r];
            q.push(u);
            while (v&&!trie[v][i])v=fail[v];
            fail[u]=trie[v][i];
        }
    }
}
inline int query()
{
    int p=0,ans=0;
    fo(i,0,len-1)
    {
        int w=s[i]-'a';
        while (p&&!trie[p][w])p=fail[p];
        p=trie[p][w];
        int o=p;
        while (o)
        {
            if (!out[o])break;
            ans+=out[o];
            out[o]=0;
            o=fail[o];
        }
    }
    return ans;
}
int main()
{
    int t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);
        memset(fail,0,sizeof(fail));
        memset(trie,0,sizeof(trie));
        memset(out,0,sizeof(out));
        tot=0;
        fo(i,1,n)
        {
            scanf("%s",ch);
            len=strlen(ch);
            insert(0,0);
        }
        getfail();
        scanf("%s",s);
        len=strlen(s);
        printf("%d\n",query());
    }
    return 0;
}

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