BZOJ3940: [Usaco2015 Feb]Censoring (AC自动机)

题意:在文本串上删除一些字符串 每次优先删除从左边开始第一个满足的

   删除后剩下的串连在一起重复删除步骤 直到不能删

题解:建fail 用栈存当前放进了那些字符 如果可以删 fail指针跳到前面去

好菜啊TAT 原来还有个优化

#include <bits/stdc++.h>
using namespace std; char t[];
char s[];
int n, cnt, tot;
int ch[][];
int val[];
int que[];
int fail[];
char ans[];
int id[]; void insert() {
int len = strlen(s); int now = ;
for(int i = ; i < len; i++) {
int c = s[i] - 'a';
if(!ch[now][c]) ch[now][c] = ++cnt;
now = ch[now][c];
}
val[now] = len;
} void getfail() {
int l1 = , r1 = ;
que[++r1] = ; while(l1 <= r1) {
int now = que[l1];
l1++; for(int i = ; i < ; i++) {
if(ch[now][i]) {
int y = fail[now];
while(!ch[y][i]) y = fail[y];
fail[ch[now][i]] = ch[y][i];
que[++r1] = ch[now][i];
}
else ch[now][i] = ch[fail[now]][i];
}
}
} void init() {
cnt = ;
tot = ;
id[] = ;
for(int i = ; i < ; i++) ch[][i] = ;
} int main() {
init();
scanf("%s", t + );
int len = strlen(t + ); scanf("%d", &n);
for(int i = ; i <= n; i++) {
scanf("%s", s);
insert();
}
getfail(); int now = ;
for(int i = ; i <= len; i++) {
int c = t[i] - 'a'; now = ch[now][c];
id[++tot] = now;
ans[tot] = t[i]; if(val[now]) {
tot -= val[now];
now = id[tot];
}
}
for(int i = ; i <= tot; i++) printf("%c", ans[i]);
puts("");
return ;
}
上一篇:BZOJ 3940: [Usaco2015 Feb]Censoring AC自动机_栈


下一篇:bzoj 3940: [Usaco2015 Feb]Censoring -- AC自动机