zoukankan      html  css  js  c++  java
  • AC自动机模板2

    AC自动机模板2

    题目

    洛谷题目传送门

    myAC自动机

    Junlier的AC自动机

    code

    #include<iostream>
    #include<cstdlib>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<iomanip>
    #include<algorithm>
    #include<ctime>
    #include<queue>
    #include<stack>
    #include<vector>
    #define rg register
    #define il inline
    #define lst long long
    #define ldb long double
    #define N 155
    #define M 10550
    using namespace std;
    const int Inf=1e9;
    
    int n,tot,cnt;
    struct STRING{
        char s[75];
        int sum,num;
    }S[N];
    struct EDGE{
        int to,nxt;
    }ljl[M];
    int hd[M];
    char T[1000050];
    int End[N],sum[M];
    int trie[M][26],fail[M];
    
    il int read()
    {
        rg int s=0,m=0;rg char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')m=1;ch=getchar();}
        while(ch>='0'&&ch<='9')s=(s<<3)+(s<<1)+(ch^48),ch=getchar();
        return m?-s:s;
    }
    
    il void init()
    {
        tot=0,cnt=0;
        memset(hd,0,sizeof(hd));
        memset(sum,0,sizeof(sum));
        memset(fail,0,sizeof(fail));
        memset(trie,0,sizeof(trie));
    }
    
    il void AC_Insert(rg char s[],rg int num)
    {
        rg int now=0,L=strlen(s);
        for(rg int i=0;i<L;++i)
        {
            rg int kk=s[i]-'a';
            if(!trie[now][kk])trie[now][kk]=++tot;
            now=trie[now][kk];
        }
        End[num]=now;
    }
    
    il void AC_get_fail()
    {
        queue<int>Q;
        while(!Q.empty())Q.pop();
        for(rg int i=0;i<26;++i)
            if(trie[0][i])Q.push(trie[0][i]);
        while(!Q.empty())
        {
            rg int now=Q.front();Q.pop();
            for(rg int i=0;i<26;++i)
                if(trie[now][i])
                {
                    fail[trie[now][i]]=trie[fail[now]][i];
                    Q.push(trie[now][i]);
                }
                else trie[now][i]=trie[fail[now]][i];
        }
    }
    
    il void AC_Query()
    {
        rg int now=0,L=strlen(T);
        for(rg int i=0;i<L;++i)
        {
            rg int kk=T[i]-'a';
            now=trie[now][kk],sum[now]++;
        }
    }
    il void add(rg int p,rg int q){ljl[++cnt]=(EDGE){q,hd[p]},hd[p]=cnt;}
    il int cmp(rg const STRING &a,rg const STRING &b)
    {
        if(a.sum==b.sum)return a.num<b.num;
        return a.sum>b.sum;
    }
    
    void dfs(rg int now)
    {
        for(rg int i=hd[now];i;i=ljl[i].nxt)
            dfs(ljl[i].to),sum[now]+=sum[ljl[i].to];
    }
    
    il void AC_get_ans()
    {
        for(rg int i=1;i<=tot;++i)
            add(fail[i],i);
        dfs(0);
        for(rg int i=1;i<=n;++i)
            S[i].sum=sum[End[i]];
        sort(S+1,S+n+1,cmp);
        printf("%d
    ",S[1].sum);
        for(rg int i=1;i<=n;++i)
        {
            if(S[i].sum!=S[1].sum)break;
            cout<<S[i].s<<endl;
        }
    }
    
    int main()
    {
        while((n=read())&&n)
        {
            init();
            for(rg int i=1;i<=n;++i)
            {
                scanf("%s",S[i].s);
                AC_Insert(S[i].s,S[i].num=i);
            }
            scanf("%s",T);
            AC_get_fail();
            AC_Query();
            AC_get_ans();
        }
        return 0;
    }
    
  • 相关阅读:
    TCP/IP、UDP、HTTP详解
    第一章 Shiro简介(学习笔记)
    [已失效]坦白说(查看好友)抓包教程+解密工具
    常用正则表达式
    计算机网络基础
    三层交换机配置实例
    计算机网络基础3
    计算机网络基础4
    计算机基础2
    Linux基础命令练习1
  • 原文地址:https://www.cnblogs.com/cjoierljl/p/9365747.html
Copyright © 2011-2022 走看看