zoukankan      html  css  js  c++  java
  • 【BZOJ2938】【luoguP2444】病毒

    description

    二进制病毒审查委员会最近发现了如下的规律:某些确定的二进制串是病毒的代码。如果某段代码中不存在任何一段病毒代码,那么我们就称这段代码是安全的。现在委员会已经找出了所有的病毒代码段,试问,是否存在一个无限长的安全的二进制代码。

    示例:

    例如如果{011, 11, 00000}为病毒代码段,那么一个可能的无限长安全代码就是010101…。如果{01, 11, 000000}为病毒代码段,那么就不存在一个无限长的安全代码。

    任务:

    请写一个程序:

    1.在文本文件WIR.IN中读入病毒代码;

    2.判断是否存在一个无限长的安全代码;

    3.将结果输出到文件WIR.OUT中。


    analysis

    • 对所有模式串建(AC)自动机,然后考虑可行的安全代码在(AC)自动机上的匹配

    • 安全代码若无限长,则必然在(AC)自动机上无限匹配、且不会匹配到失败节点

    • 注意一个节点的(fail)是失败节点,该节点也是,因为(fail)的字符串是该点字符串的后缀

    • 然后在自动机上(dfs)找出一个环,节点经过两次则有解


    code

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #include<queue>
    #define MAXN 100005
    #define ll long long
    #define reg register ll
    #define fo(i,a,b) for (reg i=a;i<=b;++i)
    #define fd(i,a,b) for (reg i=a;i>=b;--i)
    
    using namespace std;
    
    ll trie[MAXN][2],fail[MAXN],vis[MAXN];
    bool bz[MAXN],flag[MAXN];
    char s[30005];
    ll n,tot,root;
    queue<ll>q;
    
    inline ll newnode(){++tot,trie[tot][0]=trie[tot][1]=-1;return tot;}
    inline void init(){tot=0,root=newnode();}
    inline void insert(char s[])
    {
    	ll len=strlen(s),now=root;
    	fo(i,0,len-1)
    	{
    		if (trie[now][s[i]-'0']==-1)trie[now][s[i]-'0']=newnode();
    		now=trie[now][s[i]-'0'];
    	}
    	flag[now]=1;
    }
    inline void buildfail()
    {
    	q.push(root),fail[root]=root;
    	while (!q.empty())
    	{
    		ll now=q.front();q.pop();
    		fo(i,0,1)if (trie[now][i]==-1)trie[now][i]=(now==root?root:trie[fail[now]][i]);
    		else flag[trie[now][i]]|=flag[trie[fail[now]][i]],fail[trie[now][i]]=(now==root?root:trie[fail[now]][i]),q.push(trie[now][i]);
    	}
    }
    inline bool dfs(ll x)
    {
    	if (vis[x]==1)return 1;
    	if (vis[x]==-1)return 0;vis[x]=1;
    	fo(i,0,1)if (!flag[trie[x][i]]){if (dfs(trie[x][i]))return 1;}
    	vis[x]=-1;return 0;
    }
    int main()
    {
    	//freopen("P2444.in","r",stdin);
    	scanf("%lld",&n),init();
    	fo(i,1,n)scanf("%s",&s),insert(s);
    	buildfail(),printf(dfs(root)?"TAK
    ":"NIE
    ");
    	return 0;
    }
    
  • 相关阅读:
    【java】对象赋值给另一个对象
    spring boot系列(五)spring boot 配置spring data jpa (查询方法)
    Spring Data JPA 查询
    Spring Data JPA 介绍
    OpenID简介
    OAUTH协议介绍
    URL encoding(URL编码)
    RESTful 介绍
    spring boot系列(四)spring boot 配置spring data jpa (保存修改删除方法)
    spring boot 启动报 java.lang.NoClassDefFoundError: ch/qos/logback/core/spi/LifeCycle 错误
  • 原文地址:https://www.cnblogs.com/horizonwd/p/11822922.html
Copyright © 2011-2022 走看看