zoukankan      html  css  js  c++  java
  • #AC自动机#洛谷 2444 [POI2000]病毒

    题目

    给定若干01串,问是否存在无限长的01串任意子串不是给定的若干串


    分析

    如果在AC自动机上跳到了访问过的前缀即代表存在一个循环可以无限跳,
    在AC自动机上记录哪些状态是不能访问的,在AC自动机上沿trie树标记已经走过


    代码

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <queue>
    #define rr register
    using namespace std;
    const int N=30011;
    int n; char s[N];
    bool Is_Virus[N],v[N];
    struct I_AC_THE_TASK{
    	int tot,trie[N][2],fail[N];
    	inline void Insert(char *s){
            rr int len=strlen(s),now=1;
            for (rr int i=0;i<len;++i){
                if (!trie[now][s[i]^48]) trie[now][s[i]^48]=++tot;
                now=trie[now][s[i]^48];
            }
            Is_Virus[now]=1;
    	}
        inline void Build(){
            rr queue<int>q; q.push(1);
            while (!q.empty()){
                rr int x=q.front(); q.pop();
                for (rr int i=0;i<2;++i)
                if (!trie[x][i]) trie[x][i]=trie[fail[x]][i];
                    else {
                    	fail[trie[x][i]]=trie[fail[x]][i],q.push(trie[x][i]);
    					Is_Virus[trie[x][i]]|=Is_Virus[trie[fail[x]][i]];
    				}
    		}
        }
    }AC;
    inline void dfs(int x){
    	if (v[x]) printf("TAK"),exit(0);
    	if (Is_Virus[x]) return; v[x]=1;
    	if (AC.trie[x][0]) dfs(AC.trie[x][0]);
    	if (AC.trie[x][1]) dfs(AC.trie[x][1]);
    	v[x]=0;
    }
    signed main(){
    	scanf("%d",&n); AC.tot=1;
    	for (rr int i=0;i<2;++i) AC.trie[0][i]=1;
    	for (rr int i=1;i<=n;++i) scanf("%s",s),AC.Insert(s); AC.Build();
    	dfs(1);
    	return !printf("NIE");
    }
    
  • 相关阅读:
    xp安装IIS admexs.dll问题
    MySql 牛哥推荐有空看看
    PHP常用类型判断函数
    GET和POST的真正区别
    许多真理
    PHP file_put_contents() 函数
    Intellijidea建javaWeb以及Servlet简单实现
    新手上路,配置阿里云CentOS服务器LAMP
    php的socket通信
    PHP常用的一些数组操作总结
  • 原文地址:https://www.cnblogs.com/Spare-No-Effort/p/14484975.html
Copyright © 2011-2022 走看看