Luogu3132 審查(AC自動機)

2021-08-09 23:08:17 字數 1615 閱讀 6026

農夫約翰為他的奶牛們購買了乙份名字叫good hooveskeeping的定期雜誌,因此奶牛們在擠奶期間就有了大量的閱讀素材。遺憾的是在最新的一期上,有一篇有點兒不適當的文章,是關於如何烹飪完美的牛排。

fj不想讓她們看到那篇文章,(顯然,這份雜誌需要更好的編輯監督)。

fj已經採集了雜誌的所有文字,並將其建立成了乙個長度最多10^6個字元的字串。他有乙個審查出來的想要從這個字串中刪除的發生不適當內容的一組子串t1 …tn。這樣,農民約翰會找到串s中最早出現的乙個被審查出來的詞(在最開始給的單詞序列裡)並從串s中刪除它,他接著再重複這個過程,繼續在串s中刪除當前最早出現的審查出來的單詞。重複這個過程,直到s中沒有被審查出來單詞出現。注意:每次刪除操作發生後可能建立出乙個在以前串s中是不存在的新的(單詞列表中有的)單詞。

農民約翰注意到,審查出來的乙個待刪詞不會作為另乙個待刪詞的子串出現。特別的這意味著串s中最早出現的待刪詞是唯一的。

請幫助fj確定最終的審查內容

第一行包含s.

第二行包含n,即審查出來的單詞的數量。

接下來的n行包含字串t1…tn。每個字串將只包含小寫字母(範圍在a…z),並且所有這些字串的組合長度將最多是10^5。

刪除操作完成後形成的新的字串s(這裡保證刪除過程中不會出現空串)。

begintheescapexecutionatthebreakofdawn

2 escape

execution

beginthatthebreakofdawn

看到要對字串進行多串的匹配

很容易想到ac

自動機

那麼,如何解決刪完乙個串之後繼續刪下乙個串呢。

考慮用乙個棧壓一下每次匹配到的ac自動機上的節點位置

如果要退回,顯然就是把棧頂的若干個匹配完的元素彈出,繼續用棧頂匹配即可。

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

using

namespace

std;

inline

int read()

struct node

t[120000];

char ss[100000];

char c[100000];

char ss[120000];

int n,s[120000],top=0,tot;

void insert(char *s)

t[now].tot=l;

}void buildf()

}}int main()

buildf();

int now=0;

for(int i=0,l=strlen(ss);i'a'];

if(t[now].tot)

top-=t[now].tot,now=s[top+1];

}for(int i=1;i<=top;++i)

printf("%c",ss[i]);

return

0;}

3 1 32 靶子程式 外掛程式模組

1 printf n x a printf n x a a取第一行的第乙個元素的首位址,4個位元組 printf n x a 他們的區別 舉例 void main85 printf n x num 陣列名相當於第乙個元素的首位址,乙個元素有4個位元組,所以要前進4個位元組,printf n x nu...

3 1 3 2 資料成員的繫結與布局

q1 關於類成員函式中的變數與類資料成員 全域性資料之間的繫結關係 乙個 inline 函式實體,在整個類宣告未被完全看見之前,是不會被編譯器分析的 該延遲規則對引數列表中的型別名稱不起作用,型別名稱之前的繫結會在遇見時進行決議 重點 eg typedef int length int val 10...

劍指Offer(面試題31 32)

面試題31 連續子陣列的最大和 題目 輸入乙個整型陣列,陣列裡有正數也有負數。陣列中乙個或連續的多個整數組成乙個子陣列。求所有子陣列的和的最大值。要求時間複雜度為o n bool g invalidinput false int findgreatestsumofsubarray int pdata...