【NEW!】[AC自动机]AC自动机模板

RT

#include <iostream>
#include <cstdio>
#include <cstring>
#include <queue>
#define rep(i,a,b) for (i=a;i<=b;i++)
using namespace std;
struct node
{
    int edge[26],fail,cnt;
    void clear()
    {
        int i;
        rep(i,0,25)
        edge[i]=-1;
        fail=0;
        cnt=0;
    }
}a[1000001];
int rt=0,st=0;
void INSERT(string s,int rt)
{
    int len=s.length(),i;
    rep(i,0,len-1)
    {
        if (a[rt].edge[s[i]-'a']<0)
        {
            a[rt].edge[s[i]-'a']=++st;
            a[st].clear();
        }
        rt=a[rt].edge[s[i]-'a'];
    }
    a[rt].cnt++;
}
void PREPARE_FAIL()
{
    queue<int> q;
    int i;
    while (!q.empty()) q.pop();
    rep(i,0,25)
    if (a[rt].edge[i]>=0) q.push(a[rt].edge[i]);
    while (!q.empty())
    {
        int x=q.front(),x_fail;q.pop();
        rep(i,0,25)
        if (a[x].edge[i]>=0) 
        {
            q.push(a[x].edge[i]);
            x_fail=a[x].fail;
            while (x_fail>0&&a[x_fail].edge[i]<0)
            x_fail=a[x_fail].fail;
            if (a[x_fail].edge[i]>=0)
            x_fail=a[x_fail].edge[i];
            a[a[x].edge[i]].fail=x_fail;
        }
    }
}
int AC(string text)
{
    int i,cnt=0,len=text.length(),c,k=0,b;
    rep(i,0,len-1)
    {
        c=text[i]-'a';
        while (k>0&&a[k].edge[c]<0)
        k=a[k].fail;
        if (a[k].edge[c]>=0)
        {
            k=a[k].edge[c];
            b=k;
            while (b>0&&a[b].cnt!=-1)
            {
                cnt+=a[b].cnt;
                a[b].cnt=-1;
                b=a[b].fail;
            }
        }
    }
    return cnt;
}
void INIT()
{
    string model;
    int n,i;
    scanf("%d",&n);
    a[rt].clear();
    rep(i,1,n)
    {
        cin>>model;
        INSERT(model,rt);
    }
    PREPARE_FAIL();
}
void DOIT()
{
    string text;
    cin>>text;
    printf("%d",AC(text));
}
int main()
{
    INIT();
    DOIT();
}

猜你喜欢

转载自blog.csdn.net/ssl_qyh0ice/article/details/80329330