zoukankan      html  css  js  c++  java
  • bzoj3940 Censoring

    题目链接

    solution

    将所有的单词建出AC自动机。然后用母串在上面走,并且记录下在母串中的每个位置对应到AC自动机上的位置。当走到一个单词的结尾时,就回到这个单词长度之前的位置。

    问题在于如何找到这个单词长度之前的位置。我们用个栈来记录答案,每找到一个长度为len的单词,就从栈顶弹出len个位置。显然每个位置最多被弹一遍。所以总复杂度就是(O(n))的。

    code

    /*
    * @Author: wxyww
    * @Date:   2020-04-19 08:11:00
    * @Last Modified time: 2020-04-19 08:18:54
    */
    #include<cstdio>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<algorithm>
    #include<queue>
    #include<vector>
    #include<ctime>
    using namespace std;
    typedef long long ll;
    const int N = 100010;
    ll read() {
    	ll x = 0,f = 1;char c = getchar();
    	while(c < '0' || c > '9') {
    		if(c == '-') f = -1; c = getchar();
    	}
    	while(c >= '0' && c <= '9') {
    		x = x * 10 + c - '0'; c = getchar();
    	}
    	return x * f;
    }
    int trie[N][27],fail[N],tot,bz[N];
    
    char s[N],t[N];
    void insert() {
    	int n = strlen(t + 1);
    	int now = 0;
    	for(int i = 1;i <= n;++i) {
    		int x = t[i] - 'a';
    		if(!trie[now][x]) trie[now][x] = ++tot;
    		now = trie[now][x];
    	}
    	bz[now] = n;
    	// cout<<now<<endl;
    }
    queue<int>q;
    void build() {
    	for(int i = 0;i < 26;++i) if(trie[0][i]) q.push(trie[0][i]);
    
    	while(!q.empty()) {
    		int u = q.front();q.pop();
    		for(int i = 0;i < 26;++i) {
    			if(!trie[u][i]) trie[u][i] = trie[fail[u]][i];
    			else fail[trie[u][i]] = trie[fail[u]][i],q.push(trie[u][i]);
    		}
    	}
    }
    int ans[N],dy[N];
    int main() {
    	scanf("%s",s + 1);
    	int n = read();
    	for(int i = 1;i <= n;++i) {
    		scanf("%s",t + 1);
    		insert();
    	}
    	build();
    	int top = 0;
    	int m = strlen(s + 1);
    	int now = 0;
    	// cout<<tot<<endl;
    
    	for(int i = 1;i <= m;++i) {
    		now = trie[now][s[i] - 'a'];
    		dy[i] = now;
    		ans[++top] = i;
    		if(bz[now]) {
    
    			int x = bz[now];
    			top -= x;
    			now = dy[ans[top]];
    		}
    	}
    	for(int i = 1;i <= top;++i) putchar(s[ans[i]]);
    
    	return 0;
    }
    
  • 相关阅读:
    中国软件技术篇
    create pdf
    我来了
    补丁号
    rdlc里面用VB语法对数值型数据进行Format
    WinForm中有些控件不能添加ToolTip关联的解决方法
    javascript弹出对话框
    省市县关联菜单
    委托与事件
    ASP.NET多文件上传方案
  • 原文地址:https://www.cnblogs.com/wxyww/p/bzoj3940.html
Copyright © 2011-2022 走看看