正题
ybtoj AC自动机-4
题目大意
有一个字符串和若干要删除的串(不存在包含关系),每次从前往后搜,搜到第一个要删除的串然后删掉,再从0开始搜
问你最后得到的字符串
解题思路
先把所有删除串丢进AC自动机中,每个串的最后位置标注一下
然后在AC自动机中跑原串,每到一位丢进栈中,如果跑到一个删除串的结尾,那么把栈中删除的部分删掉,然后从删除串的前一位继续搜
代码
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define N 100100
using namespace std;
int n, w, top, v[N], p[N], nx[N], to[N][30];
char s[N], ss[N], a[N];
queue<int>d;
void insert(char* s)
{int n = strlen(s+1), now = 0;for (int i = 1; i <= n; ++i){int y = s[i] - 'a';if (!to[now][y]) to[now][y] = ++w;now = to[now][y];}p[now] = n;return;
}
void bfs()
{for (int i = 0; i < 26; ++i)if (to[0][i]) d.push(to[0][i]);while(!d.empty()){int h = d.front();d.pop();for (int i = 0; i < 26; ++i)if (!to[h][i]) to[h][i] = to[nx[h]][i];else nx[to[h][i]] = to[nx[h]][i], d.push(to[h][i]);}return;
}
void solve(char* s)
{int n = strlen(s+1), now = 0;for (int i = 1; i <= n; ++i){int y = s[i] - 'a';now = to[now][y];a[++top] = s[i];//丢进栈中v[top] = now;//记录位置top -= p[now];//跑到删除串就删掉now = v[top];}return;
}
int main()
{scanf("%s", ss+1);scanf("%d", &n);for (int i = 1; i <= n; ++i){scanf("%s", s+1);insert(s);}bfs();solve(ss);for (int i = 1; i <= top; ++i)putchar(a[i]);return 0;
}