BZOJ2938] [] [luoguP2444 virus

description

Binary virus Review Committee recently discovered the following rule: certain defined binary string is the virus code. If there is no section of a piece of code in the virus code, then we say the code is safe. The Commission has now identified all of the virus code segment, ask whether there is an infinite secure binary code.

Example:

For example, if {011, 11, 00000} for the virus code segment, then a possible infinite security code is 010101 .... If {01, 11, 000 000} as the virus code segment, then there is an infinitely long security code.

task:

Please write a program:

1. In reading the text file WIR.IN virus code;

. 2 determines whether there is an infinitely long security code;

3. WIR.OUT the output to a file in.


analysis

  • Built for all modes string \ (AC \) automaton, then consider the possible security code \ (AC \) match automatic machine

  • If the security code is infinitely long, it is bound in \ (AC \) unlimited match automatic machine, and does not match the node to fail

  • Note that a node \ (fail \) is a failure node that also, because \ (fail \) string is a suffix that point string

  • Then the automaton \ (DFS \) to identify a ring, the node twice solvable


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\n":"NIE\n");
    return 0;
}

Guess you like

Origin www.cnblogs.com/horizonwd/p/11822922.html