zoukankan      html  css  js  c++  java
  • 题解 P2444 【[POI2000]病毒】

    题目链接

    Solution [POI2000]病毒

    题目大意:给定若干个模式串,问能否构造出一个无限长的文本串使得其不能被任何一个模式串匹配

    AC自动机


    分析:

    首先AC自动机比较适合来搞多模匹配,我们将Trie树补全,补成一个图,然后我们文本串来做匹配就可以直接在Trie树上走了

    在这种情况下,我们匹配文本串时直接沿着补全后的Trie树上的边走,走到底暴力跳fail指针,就可以把所有匹配它的模式串找出来

    那么我们要使得没有一个模式串可以匹配文本串,就要求我们在Trie树上走到的点暴力跳fail指针能走到的点中没有一个点有标记,在这个前提下如果我们能够找到环的话就可以构造出无限长的文本串了

    我们建出AC自动机,dfs找环就可以了

    #include <cstdio>
    #include <cstdlib>
    #include <queue>
    #include <vector>
    using namespace std;
    const int maxn = 3e4 + 100;
    namespace AC{
    	int ch[maxn][2],fail[maxn],val[maxn],f[maxn],vis[maxn],ins[maxn],tot,ans;
    	inline int idx(char c){return c - '0';}
    	inline void insert(char *str){
    		int u = 0;
    		for(int i = 1;str[i];i++){
    			int c = idx(str[i]);
    			if(!ch[u][c])ch[u][c] = ++tot;
    			u = ch[u][c];
    		}
    		val[u] = 1;
    	}
    	inline void build(){
    		queue<int> Q;
    		for(int i = 0;i < 2;i++)
    			if(ch[0][i])
    				Q.push(ch[0][i]);
    		while(!Q.empty()){
    			int u = Q.front();Q.pop();
    			for(int i = 0;i < 2;i++)
    				if(ch[u][i])fail[ch[u][i]] = ch[fail[u]][i],val[ch[u][i]] |= val[fail[ch[u][i]]],Q.push(ch[u][i]);
    				else ch[u][i] = ch[fail[u]][i];
    		}
    	}
    	inline void dfs(int u = 0){
    		if(ins[u])ans = 1;
    		if(vis[u] || val[u])return;
    		ins[u] = vis[u] = 1;
    		for(int i = 0;i < 2;i++)
    			dfs(ch[u][i]);
    		ins[u] = 0;
    	}
    }
    int n;
    char str[maxn];
    int main(){
    	scanf("%d",&n);
    	for(int i = 1;i <= n;i++)scanf("%s",str + 1),AC::insert(str);
    	AC::build();
    	AC::dfs();
    	puts(AC::ans ? "TAK" : "NIE");
    	return 0;
    }
    
  • 相关阅读:
    windows通过Composer安装yii2
    jquery自定义函数
    js 回调
    读取.properties配置文件
    spring @ModelAttribute 注解
    excel导出
    spring定时器
    maven添加自己的jar包到本地仓库
    activeMq 消费者整合spring
    linux操作命令
  • 原文地址:https://www.cnblogs.com/colazcy/p/11834923.html
Copyright © 2011-2022 走看看