zoukankan      html  css  js  c++  java
  • AC自动机再加强版

    AC自动机

    拓扑排序优化,注意拓扑排序前要把所有入度为零的点都加进去

    #include<bits/stdc++.h>
    using namespace std;
    #define maxn 1000005
    #define maxm 28
    struct AC
    {
        int trieN;
        int ch[maxn][maxm];
        int val[maxn];
        int fail[maxn];
        int ans[maxn];
        int in[maxn];///用于拓扑排序
        vector<int> s[maxn];
        int tim[maxn];
        void init()
        {
            trieN=-1;
            newnod();
        }
        int newnod()
        {
            memset(ch[++trieN],0,sizeof ch[0]);
            val[trieN]=fail[trieN]=0;
            tim[trieN]=0;s[trieN].clear();
            return trieN;
        }
        void insert(const string & str,int k)
        {
            int cur=0;
            for(int i=0; i<str.size(); i++)
            {
                int d=str[i]-'a';
                if(!ch[cur][d])
                {
                    ch[cur][d]=newnod();
                }
                cur=ch[cur][d];
            }
            val[cur]++;
            s[cur].push_back(k);
        }
        void build()
        {
            queue<int> q;
            for(int i=0; i<maxm; i++)
            {
                if(ch[0][i])
                {
                    q.push(ch[0][i]);
                }
            }
           // q.push(0);
            while(!q.empty())
            {
                int cur=q.front();
                q.pop();
                for(int i=0; i<maxm; i++)
                {
                    if(ch[cur][i])
                    {
                       // cout<<cur<<' '<<i<<endl;
                       //cout<<fail[cur]<<'
    ';
                        fail[ch[cur][i]]=ch[fail[cur]][i];
                        in[fail[ch[cur][i]]]++;
                        //cout<<fail[ch[cur][i]]<<"INNNNN"<<'
    ';
                        q.push(ch[cur][i]);
                    }
                    else
                    {
                        ch[cur][i]=ch[fail[cur]][i];
                    }
                }
            }
        }
        //vector<int>ans;
        //int man=0;
        void topu()
        {
            queue<int>q;
            /*for(int i=1;i<=trieN;i++){
                cout<<i<<"IN"<<in[i]<<'
    ';
    
            }*/
            for(int i=0;i<=trieN;i++){
                if(in[i]==0){
                    q.push(i);}}
                    while(!q.empty()){
    
                        int x=q.front();
                          //cout<<x<<" "<<ans[x]<<'
    ';
                        q.pop();
                        if(val[x]){
                            for(int i=0;i<s[x].size();i++)
                            tim[s[x][i]]=ans[x];
                        }
    
                        int y=fail[x];
                        ans[y]+=ans[x];
                        in[y]--;
                        if(in[y]==0)q.push(y);
                    }
    
    
        }
        void query(const string & str)
        {
            int res=0,cur=0;
            for(int i=0; str[i]; i++)
            {
                int d=str[i]-'a';
                cur=ch[cur][d];
                ans[cur]++;
            }
        }
    } ac;
    //string A[maxn];
    int main()
    {
        string s;
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            ac.init();
            //if(n==0)break;
            for(int i=0; i<n; i++)
            {
                cin>>s;
                ac.insert(s,i);
            }
            ac.build();
            cin>>s;
            ac.query(s);
            ac.topu();
            for(int i=0;i<n;i++){
                cout<<ac.tim[i]<<'
    ';
            }
        }
    }
  • 相关阅读:
    c# XML和实体类之间相互转换(序列化和反序列化)
    反序列化-通过创建Class对象及属性
    .net C#中页面之间传值传参的六种方法
    C#对XML、JSON等格式的解析
    c#大圣之路笔记——c# DataGrid checkbox 操作
    python(十五)
    python(十四)
    python(十三)
    python(十二)
    python(十一)
  • 原文地址:https://www.cnblogs.com/liulex/p/11325415.html
Copyright © 2011-2022 走看看