1. 程式人生 > >HDU2222 Keywords Search AC自動機模板

HDU2222 Keywords Search AC自動機模板

雖然看明白了KMP和字典樹,但是AC自動機還是沒怎麼理解QAQ...

模板就用的kuangbin的模板,附上AC程式碼:

#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
#define ll long long

const int MAX=1000005;
int nex[MAX][26];
int fail[MAX];
int en[MAX];
int root,l;

int newnode()
{
    for(int i=0;i<26;i++)
        nex[l][i]=-1;
    en[l++]=0;
    return l-1;
}
void init()
{
    l=0;
    root=newnode();
}
void ins(char s[])
{
    int len=strlen(s);
    int now=root;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        if(nex[now][id]==-1)
            nex[now][id]=newnode();
        now=nex[now][id];
    }
    en[now]++;
}
void build()
{
    queue<int>q;
    fail[root]=root;
    for(int i=0;i<26;i++)
    {
        if(nex[root][i]==-1)
            nex[root][i]=root;
        else
        {
            fail[nex[root][i]]=root;
            q.push(nex[root][i]);
        }
    }
    while(!q.empty())
    {
        int now=q.front();
        q.pop();
        for(int i=0;i<26;i++)
        {
            if(nex[now][i]==-1)
                nex[now][i]=nex[fail[now]][i];
            else
            {
                fail[nex[now][i]]=nex[fail[now]][i];
                q.push(nex[now][i]);
            }
        }
    }
}
int query(char s[])
{
    int len=strlen(s);
    int now=root;
    int ans=0;
    for(int i=0;i<len;i++)
    {
        int id=s[i]-'a';
        now=nex[now][id];
        int tmp=now;
        while(tmp!=root)
        {
            ans+=en[tmp];
            en[tmp]=0;
            tmp=fail[tmp];
        }
    }
    return ans;
}

int main()
{
    char s[MAX];int n;
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&n);
        init();//注意不能少!!
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            ins(s);
        }
        build();
        scanf("%s",s);
        printf("%d\n",query(s));
    }
    return 0;
}