【USACO 2015 Feb Gold】检查
问题描述
FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S。他有一个包含n个单词的列表,列表里的n个单词记为t_1…t_N。他希望从S中删除这些单词。
FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词
FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的
请帮助FJ完成这些操作并输出最后的S
输入格式
第一行包含一个字符串S
第二行包含一个整数N
接下来的N行,每行包含一个字符串,第i行的字符串是t_i
输出格式
一行,输出操作后的S
样例输入
begintheescapexecutionatthebreakofdawn
2
escape
execution
样例输出
beginthatthebreakofdawn
提示
t_1…t_N的长度和不超过10^5
所有字符串都只包含小写字母
显然建立AC自动机进行匹配,那么考虑删除操作,用一个栈来存已匹配过的主串,那么删除时直接退栈即可,问题在于退栈后应该从AC自动机的哪一个节点开始讨论,因此需要存下主串每一个位置匹配后在AC自动机上的位置,那么退栈时只要跑到之前存下的位置即可。
需要注意的是建立Fail指针的时候,某些写法会超时,背一个优秀的模板。(有限状态自动机)
代码:
1 |
|