1. 程式人生 > >P3121 [USACO15FEB]審查(黃金)Censoring (Gold)

P3121 [USACO15FEB]審查(黃金)Censoring (Gold)

next character turn pty %d 註意 nbsp eterm fail

題目描述

Farmer John has purchased a subscription to Good Hooveskeeping magazine for his cows, so they have plenty of material to read while waiting around in the barn during milking sessions. Unfortunately, the latest issue contains a rather inappropriate article on how to cook the perfect steak, which FJ would rather his cows not see (clearly, the magazine is in need of better editorial oversight).

FJ has taken all of the text from the magazine to create the string S of length at most 10^5 characters. He has a list of censored words t_1 ... t_N that he wishes to delete from S. To do so Farmer John finds the earliest occurrence of a censored word in S (having the earliest start index) and removes that instance of the word from S. He then repeats the process again, deleting the earliest occurrence of a censored word from S, repeating until there are no more occurrences of censored words in S. Note that the deletion of one censored word might create a new occurrence of a censored word that didn‘t exist before.

Farmer John notes that the censored words have the property that no censored word appears as a substring of another censored word. In particular this means the censored word with earliest index in S is uniquely defined.

Please help FJ determine the final contents of S after censoring is complete.

FJ把雜誌上所有的文章摘抄了下來並把它變成了一個長度不超過10^5的字符串S。他有一個包含n個單詞的列表,列表裏的n個單詞記為t_1...t_N。他希望從S中刪除這些單詞。

FJ每次在S中找到最早出現的列表中的單詞(最早出現指該單詞的開始位置最小),然後從S中刪除這個單詞。他重復這個操作直到S中沒有列表裏的單詞為止。註意刪除一個單詞後可能會導致S中出現另一個列表中的單詞

FJ註意到列表中的單詞不會出現一個單詞是另一個單詞子串的情況,這意味著每個列表中的單詞在S中出現的開始位置是互不相同的

請幫助FJ完成這些操作並輸出最後的S

輸入輸出格式

輸入格式:

The first line will contain S.

The second line will contain N, the number of censored words. The next N lines contain the strings t_1 ... t_N. Each string will contain lower-case alphabet characters (in the range a..z), and the combined lengths of all these strings will be at most 10^5.

輸出格式:

The string S after all deletions are complete. It is guaranteed that S will not become empty during the deletion process.

輸入輸出樣例

輸入樣例#1:
begintheescapexecutionatthebreakofdawn 
2 
escape 
execution 
輸出樣例#1:
beginthatthebreakofdawn 

Solution:

  Water!本題和前面那題思路完全一樣,只不過變成了多模式串,只需將模式串建好AC自動機,每次用棧記錄失配邊所指向的節點,然後若匹配到了一個模式串就回到當前節點深度之前的棧中的節點,繼續匹配就好了。

代碼:

 1 #include<bits/stdc++.h>
 2 #define il inline
 3 #define ll long long
 4 #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
 5 #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
 6 using namespace std;
 7 const int N=1e5+7;
 8 int trie[N][26],cnt,fail[N],lst[N],ed[N],n,dep[N],stk[N],tot;
 9 char s[N],t[N],ans[N];
10 
11 il void insert(char *s){
12     int len=strlen(s),p=0,x;
13     For(i,0,len-1){
14         x=s[i]-a;
15         if(!trie[p][x])trie[p][x]=++cnt,dep[cnt]=dep[p]+1;
16         p=trie[p][x];
17     }
18     ed[p]++;
19 }
20 
21 il void bfs(){
22     queue<int>q;
23     For(i,0,25) if(trie[0][i]) q.push(trie[0][i]),fail[trie[0][i]]=0;
24     while(!q.empty()){
25         int u=q.front();q.pop();
26         For(i,0,25){
27             int &v=trie[u][i];
28             if(v) fail[v]=trie[fail[u]][i],lst[v]=ed[fail[v]]?fail[v]:lst[fail[v]],q.push(v);
29             else v=trie[fail[u]][i];
30         }
31     }
32 }
33 
34 il void solve(char *s){
35     int len=strlen(s),p=0;
36     For(i,0,len-1){
37         ans[++tot]=s[i];
38         p=trie[p][s[i]-a];
39         for(int j=p;j;j=lst[j]) if(ed[j]){tot-=dep[j];p=stk[tot];break;}
40         stk[tot]=p;
41     }
42     For(i,1,tot) printf("%c",ans[i]);
43 }
44 
45 il void init(){
46     scanf("%s%d",t,&n);
47     For(i,1,n)scanf("%s",s),insert(s);
48     bfs();
49     solve(t);
50 }
51 
52 int main(){
53     init();
54     return 0;
55 }

P3121 [USACO15FEB]審查(黃金)Censoring (Gold)