zoukankan      html  css  js  c++  java
  • [USACO15FEB][AC自动机][栈] Censoring G

    题面

    看到这种匹配题总会想到 (AC) 自动机 (

    实际我们匹配的时候只需要多加两个栈:一个用于记录下一个匹配的位置,一个用于记录答案,分别记为 (S_{tmp})(S_{ans})
    (S_{tmp}) 栈顶每加入字符串上的一个位置,就将其记录到 (S_{ans}) 中;
    如果字符串上匹配到了一个子串,两个栈就都就跳转到这个子串开头的位置。
    这样就可以完成匹配了,最后输出 (S_{ans}) 即可。

    代码

    # include <iostream>
    # include <cstdio>
    # include <string>
    # include <queue>
    # define MAXN 1000005
    
    int trie[MAXN][26], cntT;
    int isEnd[MAXN], fail[MAXN];
    int ansS[MAXN], tmpS[MAXN], topS;
    
    void Insert(std::string s){
    	int now = 0, len = s.length();
    
    	for(int i = 0, ch; i < len; i++){
    		ch = s[i] - 'a';
    
    		if(!trie[now][ch]){
    			trie[now][ch] = ++cntT;
    		}
    
    		now = trie[now][ch];
    	}
    
    	isEnd[now] = len;
    }
    
    void InitFail(){
    	std::queue<int>Q;
    
    	for(int i = 0; i < 26; i++){
    		if(trie[0][i]){
    			fail[trie[0][i]] = 0;
    			Q.push(trie[0][i]);
    		}
    	}
    
    	while(Q.size()){
    		int now = Q.front(); Q.pop();
    
    		for(int i = 0; i < 26; i++){
    			if(trie[now][i]){
    				fail[trie[now][i]] = trie[fail[now]][i];
    				Q.push(trie[now][i]);
    			}
    			else{
    				trie[now][i] = trie[fail[now]][i];
    			}
    		}
    	}
    }
    
    void Query(std::string s){
    	int now = 0, len = s.length();
    
    	for(int i = 0, ch; i < len; i++){
    		ch = s[i] - 'a';
    		now = trie[now][ch];
    
    		tmpS[++topS] = now;
    		ansS[topS] = i; 
    
    		if(isEnd[now]){
    			topS -= isEnd[now]; // 查到一个单词直接跳到单词开头重新匹配
    			if(!topS){
    				now = 0;
    			}
    			else{
    				now = tmpS[topS];
    			}
    		}
    	}
    
    }
    
    int main(){
    	std::string s, t;
    	int n;
    
    	std::cin>>s>>n;
    
    	for(int i = 1; i <= n; i++){
    		std::cin>>t;
    		Insert(t);
    	}
    
    	InitFail();
    
    	Query(s);
    
    	for(int i = 1; i <= topS; i++){
    		std::cout<<s[ansS[i]];
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    2月8日
    2月7日
    2月6日
    2月5日
    事务
    synchronized关键字详解(二)
    synchronized关键字详解(一)
    java.sql.SQLException: Access denied for user 'somebody'@'localhost' (using password: YES)
    wex5 教程 之 图文讲解 wex5集成HTML5 视频播放器
    wex5 实战 加密与解密系列(1) DES算法引入与调用
  • 原文地址:https://www.cnblogs.com/Foggy-Forest/p/13626709.html
Copyright © 2011-2022 走看看