HDU 5880 Family View (2016 青岛网络赛 C题,AC自动机)

题目链接  2016 青岛网络赛  Problem C

题意  给出一些敏感词,和一篇文章。现在要屏蔽这篇文章中所有出现过的敏感词,屏蔽掉的用$'*'$表示。

 

建立$AC$自动机,查询的时候沿着$fail$指针往下走,当匹配成功的时候更新$f[i]$

$f[i]$表示要屏蔽以第$i$个字母结尾的长度为$f[i]$的字符串。

 

#include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b)    for (int i(a); i <= (b); ++i)
#define dec(i, a, b)    for (int i(a); i >= (b); --i)
#define fi        	first
#define se        	second

typedef long long LL;

const int N = 1e6 + 10;

int T, n;
int f[N];
char buf[N];

struct Trie{

	int nxt[N][26], fail[N], end[N], len[N];
	int root, tot;
	int newnode(){
		rep(i, 0, 25) nxt[tot][i] = -1;
		len[tot] = end[tot] = 0; tot++;
		return tot - 1;
	}

	void init(){
		tot = 0;
		root = newnode();
	}

	void ins(char buf[]){
		int l = strlen(buf);
		int now = root;
		rep(i, 0, l - 1){
			if (nxt[now][buf[i] - 'a'] == -1) nxt[now][buf[i] - 'a'] = newnode();
			now = nxt[now][buf[i] - 'a'];
		}
		end[now]++;
		len[now] = strlen(buf);
	}

	void build(){
		queue <int> q;
		fail[root] = root;
		rep(i, 0, 25){
			if (~nxt[root][i]){
				fail[nxt[root][i]] = root;
				q.push(nxt[root][i]);
			} 
			else nxt[root][i] = root;
		}

		while (!q.empty()){
			int now = q.front();
			q.pop();
			rep(i, 0, 25){
				if (~nxt[now][i]){
					fail[nxt[now][i]] = nxt[fail[now]][i];
					q.push(nxt[now][i]);
				} 
				else nxt[now][i] = nxt[fail[now]][i];
			}
		}
	}

	void query(char buf[]){
		int l = strlen(buf);
		int now = root;
		int res = 0;
		rep(i, 0, l - 1){
			int sign;
			if (buf[i] >= 'A' && buf[i] <= 'Z') sign = buf[i] - 'A';
			else if (buf[i] >= 'a' && buf[i] <= 'z') sign = buf[i] - 'a';
			else{
				now = root;
				continue;
			}
			now = nxt[now][sign];
			int temp = now;
			while (temp != root){
				f[i] = max(f[i], len[temp]);
				temp = fail[temp];
			}
		}
	}
} ac;

int leng, num;

int main(){

	scanf("%d",&T);
	while (T--){
		scanf("%d",&n);
		ac.init();
		rep(i, 1, n){
			scanf("%s", buf);
			ac.ins(buf);
		}

		ac.build();

		getchar();
		gets(buf);
		memset(f, 0, sizeof f);

		ac.query(buf);
		leng = strlen(buf);
		num  = 0;

		dec(i, leng - 1, 0){
			num = max(num, f[i]);
			if (num == 0) continue;
			else buf[i] = '*', num--;
		}

		puts(buf);
	}
	return 0;
}

 

  

 

posted @ 2018-02-17 20:37  cxhscst2  阅读(185)  评论(0编辑  收藏  举报