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
  • 相关阅读:
    %u编码
    总结
    windows7 安装PHP7 本地网站搭建
    统计某个端口的链接数
    mysql连结查询
    mysql in
    读书笔记<白帽子讲web安全>
    Web攻防系列教程之文件上传攻防解析(转载)
    攻防:文件上传漏洞的攻击与防御
    weblogic检查项
  • 原文地址:https://www.cnblogs.com/gcfer/p/12739907.html
Copyright © 2011-2022 走看看