AC自动机模板

贴份模板

胡大神和崔大神的组合模板

#include <iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<stdlib.h>
#include<vector>
#include<cmath>
#include<queue>
#include<set>
using namespace std;
#define N 1000010
#define LL long long
#define INF 0xfffffff
#define maxch 26
const double eps = 1e-8;
const double pi = acos(-1.0);
const double inf = ~0u>>2;
const int child_num = 26;
char ss[N];
class ACAutomation
{
    private:
    int ch[N][maxch];
    int val[N];
    int fail[N];
    int Q[N];
    int id[128];
    int sz;
   // int dp[2][N][1<<10];
    public:
    void init()
    {
        fail[0] = 0;
        for(int i = 0 ; i < child_num;  i++)
        id[i+'a'] = i;
    }
    void reset()//初始化
    {
        memset(ch[0],0,sizeof(ch[0]));
        memset(val,0,sizeof(val));
        sz = 1;
    }
    void insert(char *a,int key)//建立trie树
    {
        int p = 0;
        for( ; *a ; a++)
        {
            int c = id[*a];
            if(ch[p][c]==0)
            {
                memset(ch[sz],0,sizeof(ch[sz]));
                val[sz] = 0;
                ch[p][c] = sz++;
            }
            p = ch[p][c];
        }
        val[p] += key;
    }
    void construct()//构建fail指针
    {
        int head = 0,tail = 0,i;
        for(i = 0 ;i < child_num ; i++)
        {
            if(ch[0][i])
            {
                fail[ch[0][i]] = 0;
                Q[tail++] = ch[0][i];
            }
        }
        while(head!=tail)
        {
            int u = Q[head++];
            for(i = 0 ;i < child_num ;i ++)
            {
                if(ch[u][i]!=0)
                {
                    Q[tail++] = ch[u][i];
                    fail[ch[u][i]] = ch[fail[u]][i];
                }
                else
                ch[u][i] = ch[fail[u]][i];
            }
        }
    }
    int work(char *s)
    {
        int k = strlen(s);
        int p = 0,ans = 0;
        for(int i = 0; i < k ; i++)
        {
            int d = s[i]-'a';
            p = ch[p][d];
            int tmp = p;
            while(tmp!=0&&val[tmp]!=0)
            {
                ans+=val[tmp];
                val[tmp] = 0;
                tmp = fail[tmp];
            }
        }
        return ans;
    }

}ac;
int main()
{
    int t,n;
    char word[55];
    ac.init();
    cin>>t;
    while(t--)
    {
        cin>>n;
        ac.reset();
        while(n--)
        {
            scanf("%s",word);
            ac.insert(word,1);
        }
        ac.construct();
        scanf("%s",ss);
        printf("%d\n",ac.work(ss));
    }
    return 0;
}

 

 

posted @ 2014-05-14 13:22  _雨  阅读(265)  评论(0编辑  收藏  举报