USACO 2015 February Contest Gold T2: Censoring

Posted li-dox

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了USACO 2015 February Contest Gold T2: Censoring相关的知识,希望对你有一定的参考价值。

题目大意

FJ把杂志上所有的文章摘抄了下来并把它变成了一个长度不超过10^5的字符串S。他有一个包含n个单词的列表,列表里的n个单词记为t1...tN。他希望从S中删除这些单词。

FJ每次在S中找到最早出现的列表中的单词(最早出现指该单词的开始位置最小),然后从S中删除这个单词。他重复这个操作直到S中没有列表里的单词为止。注意删除一个单词后可能会导致S中出现另一个列表中的单词

FJ注意到列表中的单词不会出现一个单词是另一个单词子串的情况,这意味着每个列表中的单词在S中出现的开始位置是互不相同的

请帮助FJ完成这些操作并输出最后的S

题目分析

我们通过观察,容易得出我们要做的是多模式串匹配,考虑使用AC自动机。

用两个栈分别记录扫到当前字符x,一个记录当前栈内的所有字符,另一个对应记录这些字符在AC自动机上的位置(节点号)。

当我们走到一个可行节点时,把两个栈都弹出 当前节点表示的模式串的长度 个元素,相当于题目中的删除操作。这样一边下来即可得到答案。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int MAXN=1e5+10;
 4 
 5 char s[MAXN],word[MAXN];
 6 int n,top;
 7 int sta[MAXN],sgn[MAXN];
 8 struct AC_Automation
 9     int tot;
10     int Trie[MAXN][27],fail[MAXN],num[MAXN];
11     
12     inline void Insert(char *s)
13         int p=0,len=strlen(s);
14         for(int i=0,x;i<len;++i)
15             x=s[i]-a;
16             if(!Trie[p][x]) Trie[p][x]=++tot;
17             p=Trie[p][x];
18         
19         num[p]=len;
20     
21     inline void Make_Fail()
22         queue<int> q;
23         for(int i=0;i<26;++i)
24             if(Trie[0][i])
25                 q.push(Trie[0][i]);
26         while(!q.empty())
27             int x=q.front();q.pop();
28             for(int i=0;i<26;++i)
29                 if(!Trie[x][i])
30                     Trie[x][i]=Trie[fail[x]][i];
31                     continue;
32                 
33                 fail[Trie[x][i]]=Trie[fail[x]][i];
34                 q.push(Trie[x][i]);
35             
36         
37     
38     inline void Solve(char *s)
39         int p=0,x,len=strlen(s),i=0;
40         while(i<len)
41             x=s[i]-a;
42             p=Trie[p][x];
43             sgn[++top]=p;
44             sta[top]=i;
45             if(num[p])
46                 top-=num[p];
47                 if(!top) p=0;
48                 else p=sgn[top];
49             
50             ++i;
51         
52         
53     
54 AC; 
55 
56 int main()
57     scanf("%s%d",s,&n);
58     for(int i=1;i<=n;++i)
59         scanf("%s",word);
60         AC.Insert(word);
61     
62     AC.Make_Fail();
63     AC.Solve(s);
64     for(int i=1;i<=top;++i)
65         printf("%c",s[sta[i]]);
66     return 0;
67 

 

以上是关于USACO 2015 February Contest Gold T2: Censoring的主要内容,如果未能解决你的问题,请参考以下文章

Aggressive cows (USACO 2005 February Gold) (二分查找)

USACO 2019 February Contest Platinum T1: Cow Dating

6319. 省选组USACO 2019 February PlatinumProblem 3. Mowing Mischief

6319. 省选组USACO 2019 February PlatinumProblem 3. Mowing Mischief

Usaco2015 FEBCow Hopscotch (Gold)

BZOJ 3942: [Usaco2015 Feb]Censoring