• 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
    ",ac.work(ss));
        }
        return 0;
    }
  • 相关阅读:
    DbEntry——学习笔记(二)
    新的开始
    Jquery Dialog的使用
    使用System.Net.Mail.MailMessage 来发送邮件
    三层架构中的"业务逻辑层"
    Ajax请求中的async:false/true的作用
    1
    招聘会项目的开发
    操作全角与半角(C#)
    sqlserver把数据库中的表完整的复制到另一个数据库
  • 原文地址:https://www.cnblogs.com/shangyu/p/3727513.html
Copyright © 2020-2023  润新知