• BZOJ_2938_[Poi2000]病毒_AC自动机


    BZOJ_2938_[Poi2000]病毒_AC自动机

    Description

    二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。
    示例:
    例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。
    任务:
    请写一个程序:
    l         读入病毒代码;
    l         判断是否存在一个无限长的安全代码;
    l         将结果输出

    Input

     
    第一行包括一个整数n,表示病毒代码段的数目。以下的n行每一行都包括一个非空的01字符串——就是一个病毒代码段。所有病毒代码段的总长度不超过30000。

    Output

    你应在在文本文件WIN.OUT的第一行输出一个单词:
    l         TAK——假如存在这样的代码;
    l         NIE——如果不存在。

    Sample Input

    3
    01
    11
    00000

    Sample Output

    NIE


    $trie$ 图真的是比$AC$ 自动机好写多了。

    存在这样的字符串,当且仅当在$trie$ 图上存在一个不包括病毒代码的环。

    具体操作:建个$trie$ 树,终止处打上标记,在建$fail$ 的时候把子树也标记上。

    代码:

    #include <stdio.h>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    #define N 2050
    #define M 60050
    char w[M];
    int ch[M][2],cnt[M],tot=1,n,Q[M],l,r,fail[M],vis[M],ins[M];
    void insert() {
        int p=1,i;
        for(i=0;w[i];i++) {
            int &k=ch[p][w[i]-'0'];
            if(!k) k=++tot;
            p=k;
        }
        cnt[p]=1;
    }
    void build() {
        int p,i;
        for(i=0;i<2;i++) ch[0][i]=1;
        Q[r++]=1;
        while(l<r) {
            p=Q[l++];
            for(i=0;i<2;i++) {
                if(ch[p][i]) fail[ch[p][i]]=ch[fail[p]][i],Q[r++]=ch[p][i];
                else ch[p][i]=ch[fail[p]][i];
                cnt[p]|=cnt[fail[p]];
            }
        }
    }
    bool dfs(int x) {
        vis[x]=1;
        ins[x]=1;
        int i,t;
        for(i=0;i<2;i++) {
            t=ch[x][i];
            if(ins[t]||(!vis[t]&&!cnt[t]&&dfs(t))) return 1;
        }
        ins[x]=0;
        return 0;
    }
    int main() {
        scanf("%d",&n);
        int i;
        for(i=1;i<=n;i++) {
            scanf("%s",w);
            insert();
        }
        build();
        puts(dfs(1)?"TAK":"NIE");
    }
    
  • 相关阅读:
    关于虚拟机链接本地磁盘文件的问题
    javaScript学习笔记
    html学习笔记
    eclipse svn插件安装
    python学习笔记一

    hive数据处理
    WordCount实验
    暑假第六周总结
    暑假第五周总结
  • 原文地址:https://www.cnblogs.com/suika/p/8891891.html
Copyright © 2020-2023  润新知