bzoj 2938 病毒 AC自动机

来源:互联网 发布:淘宝旗舰店假货 编辑:程序博客网 时间:2024/05/22 10:29

在补全之后的AC自动机上顺着child找环而不经过终止节点,如果存在环,则说明我们可以顺着这条路径构造无限长的字符串。

#include<queue>#include<cstdio>#include<cstring>#include<iostream>#define maxn 100005using namespace std;char s[maxn];struct Trie{    bool val[maxn];    int fail[maxn];    int ch[maxn][2],cnt;    void insert()    {        int p=0;        int n=strlen(s+1);        for(int i=1;i<=n;i++)        {            int c=s[i]-'0';            if(!ch[p][c]) ch[p][c]=++cnt;            p=ch[p][c];        }        val[p]=1;    }    queue<int> Q;    void build()    {        for(int i=0;i<=1;i++)            if(ch[0][i]) Q.push(ch[0][i]);        while(!Q.empty())        {            int r=Q.front();Q.pop();            for(int i=0;i<=1;i++)            {                int u=ch[r][i];                if(!u)                {                    ch[r][i]=ch[fail[r]][i];                    continue;                }                Q.push(u);                int p=fail[r];                while(p&&!ch[p][i]) p=fail[p];                fail[u]=ch[p][i];                val[u]|=val[fail[u]];            }        }    }    bool ins[maxn];    bool vis[maxn];    bool dfs(int x)    {        bool can=0;        ins[x]=vis[x]=1;        for(int i=0;i<=1;i++)        {            int v=ch[x][i];            if(!val[v])             {                if(vis[v])return true;                if(!ins[v]&&dfs(v))return true;            }        }        vis[x]=0;        return false;    }}AC;int main(){    int n;    scanf("%d",&n);    for(int i=1;i<=n;i++)    {        scanf("%s",s+1);        AC.insert();    }    AC.build();    if(AC.dfs(0)) puts("TAK");    else puts("NIE");    return 0;}
1 0
原创粉丝点击