zoukankan      html  css  js  c++  java
  • hdoj3065(AC自动机简单题)

    题目链接:https://vjudge.net/problem/HDU-3065

    题意:给定n个不相同的模式串,模式串总长<=5e4。给定文本串,长度<=2e6。求各个模式串在文本串中出现次数。


    思路:

      AC自动机简单题。因为要输出次数,所以用到了拓扑排序优化版本的AC自动机。用key[u]表示以u结点结束的模式串编号,res[u]表示文本中以u为结尾的次数(拓扑排序优化版本中不用沿fail循环,那样会T),用in[u]表示入度。 

      另外这题是多组输入,比较坑!

    AC code:

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    using namespace std;
    
    const int maxt=5e4+5;
    const int maxn=1e3+5;
    int n,cnt,trie[maxt][130],key[maxt],res[maxt],in[maxt],fail[maxt];
    int ans[maxn];
    char s[maxn][55],ss[2000005];
    
    void build(char *s,int k){
        int len=strlen(s),u=0;
        for(int i=0;i<len;++i){
            int t=s[i];
            if(!trie[u][t]){
                ++cnt;
                memset(trie[cnt],0,sizeof(trie[cnt]));
                key[cnt]=0,fail[cnt]=0,res[cnt]=0,in[cnt]=0;
                trie[u][t]=cnt;
            }
            u=trie[u][t];
        }
        key[u]=k;
    }
    
    void get_fail(){
        queue<int> que;
        for(int i=0;i<130;++i)
            if(trie[0][i]){
                fail[trie[0][i]]=0;
                que.push(trie[0][i]);
            }
        while(!que.empty()){
            int u=que.front();que.pop();
            for(int i=0;i<130;++i){
                if(trie[u][i]){
                    fail[trie[u][i]]=trie[fail[u]][i];
                    ++in[trie[fail[u]][i]];
                    que.push(trie[u][i]);
                }
                else{
                    trie[u][i]=trie[fail[u]][i];
                }
            }
        }
    }
    
    void query(char *s){
        int len=strlen(s),u=0;
        for(int i=0;i<len;++i){
            int t=s[i];
            u=trie[u][t];
            ++res[u];
        }
    }
    
    void topu(){
        queue<int> que;
        for(int i=1;i<=cnt;++i)
            if(!in[i])
                que.push(i);
        while(!que.empty()){
            int u=que.front();que.pop();
            ans[key[u]]+=res[u];
            int v=fail[u];
            --in[v];
            res[v]+=res[u];
            if(!in[v]) que.push(v);
        }
    }
    
    int main(){
        while(~scanf("%d",&n)){
            memset(trie[0],0,sizeof(trie[0]));
            key[0]=0,res[0]=0,in[0]=0;
            cnt=0;
            for(int i=1;i<=n;++i)
                ans[i]=0;
            for(int i=1;i<=n;++i){
                scanf("%s",s[i]);
                build(s[i],i);
            }
            fail[0]=0;
            get_fail();
            scanf("%s",ss);
            query(ss);
            topu();
            for(int i=1;i<=n;++i)
                if(ans[i])
                    printf("%s: %d
    ",s[i],ans[i]);
        }
        return 0;
    }
  • 相关阅读:
    axublogcms1.1.0 Getshell
    易酷 cms2.5 本地文件包含漏洞 getshell
    通过 phpmyadmin getshell
    python 简单图像识别--验证码
    Linux 入侵检测小结
    beef + msf 实现内网渗透
    phpwind v9存在命令执行漏洞(登陆后台)
    缓冲区溢出实践
    《Metasploit魔鬼训练营》第四章(下)
    《Metasploit魔鬼训练营》第四章(上)
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/12523968.html
Copyright © 2011-2022 走看看