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

    放三个板子

    板子1:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e6;
    int tire[N][26],fail[N],n,tot=1,end[N],ans;
    char str[N];
    inline void insert(char *a)
    {
        int n=strlen(a+1),p=1;
        for(int i=1;i<=n;++i)
        {
            int ch=a[i]-'a';
            if(!tire[p][ch]) tire[p][ch]=++tot;
            p=tire[p][ch];
        }
        end[p]++;
    }
    inline void get_fail()
    {
        queue<int>q;q.push(1);
        fail[1]=0;
        for(int i=0;i<26;++i) tire[0][i]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=0;i<26;++i)
            {
                if(!tire[x][i]) {tire[x][i]=tire[fail[x]][i];continue;}
                fail[tire[x][i]]=tire[fail[x]][i];q.push(tire[x][i]); 
            }
        }
    }
    inline int AC(char *a)
    {
        int n=strlen(a+1),p=1;
        for(int i=1;i<=n;++i)
        {
            int ch=a[i]-'a';
            int k=tire[p][ch];
            while(k>1&&end[k]!=-1)
            {
                ans+=end[k];end[k]=-1;
                k=fail[k];
            }
            p=tire[p][ch];
        }
        return ans;
    }
    int main()
    {
        freopen("1.in","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%s",str+1);
            insert(str);
        }
        get_fail();
        scanf("%s",str+1);
        printf("%d",AC(str));
        return 0;
    } 
    View Code

    板子2:

    #include<bits/stdc++.h>
    using namespace std;
    const int N=1e5,qwq=1e6+10;
    int n,tire[N][26],tot=1,end[N],cnt[N],fail[N];
    char str[200][100];
    char ch[qwq];
    inline void insert(char *a,int s)
    {
        int n=strlen(a+1),p=1;
        for(int i=1;i<=n;++i)
        {
            int ch=a[i]-'a';
            if(!tire[p][ch]) tire[p][ch]=++tot;
            p=tire[p][ch];
        }
        end[p]=s;
    }
    inline void get_fail()
    {
        queue<int>q;q.push(1);
        fail[1]=0;
        for(int i=0;i<26;++i) tire[0][i]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=0;i<26;++i)
            {
                if(!tire[x][i]) {tire[x][i]=tire[fail[x]][i];continue;}
                fail[tire[x][i]]=tire[fail[x]][i];q.push(tire[x][i]);
            }
        }
    }
    inline void AC(char *a)
    {
        int m=strlen(a+1),p=1;
        for(int i=1;i<=m;++i)
        {
            int ch=a[i]-'a';
            int k=tire[p][ch];
            while(k>1)
            {
                cnt[end[k]]++;
                k=fail[k];
            }
            p=tire[p][ch];
            //cout<<i<<' '<<cnt[1]<<' '<<cnt[2]<<endl;
        }
        int mx=0;
        for(int i=1;i<=n;++i) mx=max(mx,cnt[i]);
        printf("%d
    ",mx);
        for(int i=1;i<=n;++i)
            if(cnt[i]==mx) printf("%s
    ",str[i]+1);
    }
    int main()
    {
        freopen("1.in","r",stdin);
        while(scanf("%d",&n))
        {
            if(n==0) break;
            memset(tire,0,sizeof(tire));
            memset(fail,0,sizeof(fail));
            memset(end,0,sizeof(end));
            memset(cnt,0,sizeof(cnt));
            tot=1;
            for(int i=1;i<=n;++i)
            {
                scanf("%s",str[i]+1);
                insert(str[i],i);
            }
            get_fail();
            scanf("%s",ch+1);
            AC(ch);
        }
        return 0;
    }
    View Code

    板子3(拓扑优化):

    #include<bits/stdc++.h>
    using namespace std;
    const int N=2e6;
    int tire[N][26],fail[N],n,tot=1,end[N],ans;
    char str[N];
    inline void insert(char *a)
    {
        int n=strlen(a+1),p=1;
        for(int i=1;i<=n;++i)
        {
            int ch=a[i]-'a';
            if(!tire[p][ch]) tire[p][ch]=++tot;
            p=tire[p][ch];
        }
        end[p]++;
    }
    inline void get_fail()
    {
        queue<int>q;q.push(1);
        fail[1]=0;
        for(int i=0;i<26;++i) tire[0][i]=1;
        while(!q.empty())
        {
            int x=q.front();q.pop();
            for(int i=0;i<26;++i)
            {
                if(!tire[x][i]) {tire[x][i]=tire[fail[x]][i];continue;}
                fail[tire[x][i]]=tire[fail[x]][i];q.push(tire[x][i]); 
            }
        }
    }
    inline int AC(char *a)
    {
        int n=strlen(a+1),p=1;
        for(int i=1;i<=n;++i)
        {
            int ch=a[i]-'a';
            int k=tire[p][ch];
            while(k>1&&end[k]!=-1)
            {
                ans+=end[k];end[k]=-1;
                k=fail[k];
            }
            p=tire[p][ch];
        }
        return ans;
    }
    int main()
    {
        freopen("1.in","r",stdin);
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%s",str+1);
            insert(str);
        }
        get_fail();
        scanf("%s",str+1);
        printf("%d",AC(str));
        return 0;
    }
    View Code
  • 相关阅读:
    【矩阵乘】【DP】【codevs 1305】Freda的道路
    Giraph源代码分析(九)—— Aggregators 原理解析
    Dubbo框架应用之(三)--Zookeeper注冊中心、管理控制台的安装及解说
    Oracle中对数字加汉字的排序(完好)
    PKU-2104-K-th Number
    IE下推断IE版本号的语句
    自己定义View时,用到Paint Canvas的一些温故,简单的帧动画(动画一 ,&quot;掏粪男孩Gif&quot;顺便再提提onWindowFocusChanged)
    <html>
    测试一个网段主机在线情况,禁ping的情况除外
    glance image-create --name "wj_js_company_img" --file a0e1c7fa-d6d3-410f-9bb5-e699e342db91 --disk-format qcow2 --container-format bare --progress --visibility public
  • 原文地址:https://www.cnblogs.com/gcfer/p/12739907.html
Copyright © 2011-2022 走看看