BZOJ3172 AC自動機 fail樹

2021-08-18 16:34:42 字數 1029 閱讀 2877

description

某人讀**,一篇**是由許多單詞組成。但他發現乙個單詞會在**中出現很多次,現在想知道每個單詞分別在**中出現多少次。

input

第乙個乙個整數n,表示有多少個單詞,接下來n行每行乙個單詞。每個單詞由小寫字母組成,n<=200,單詞長度不超過10^6

output

輸出n個整數,第i行的數字表示第i個單詞在文章中出現了多少次。

sample inputaaa

aaa

sample output

這道題需要我們求每個字串在所有字串構成的trie裡的出現次數。如果我們乙個乙個去匹配,那肯定會超時,所以我們要用更優的方法。這裡就需要用每個節點的fail去構建一棵樹,稱為fail樹。

如果我們每次將點x向它的fail相連,那麼所得的樹就會有乙個非常神奇的特點,也就是從根到點fail[x]的子串必定為根到x的子串的字尾。所以也就是說,如果我們要統計字串s在所有字串裡出現的次數,就只需要在fail樹上它的子樹裡找即可。具體的找法如下:我們採用從葉子節點到根的做法,先從最下面的葉子節點開始,將sz[fail[x]]加上sz[x],這樣一直往上更新,就可以求出答案。因為更新是累加的,所以可以保證向上的遞增,而由於每次都向上跳fail[x],所以可以保證跳到的是當前字串的字尾,可以繼續累加答案,這樣就保證了正確性。

code:

#include

using namespace std;

intread()

int n,cnt,bel[1500000],q[1500000];

string s;

struct nodef[1500000];

void build(string s,int num)

f[pl].sz++;

}bel[num]=pl;

}void fail()

}void match()

int main()

fail();

match();

return

0;}

bzoj3172 AC自動機 fail樹

bzoj3172 tjoi2013 單詞 time limit 10 sec memory limit 512 mb 某人讀 一篇 是由許多單詞組成。但他發現乙個單詞會在 中出現很多次,現在想知道每個單詞分別在 中出現多少次。input 第乙個乙個整數n,表示有多少個單詞,接下來n行每行乙個單詞。每...

BZOJ 3172 單詞 (AC自動機)

這道題是個裸的ac自動機,但是我還是調了很久qaq。首先如果我們直接用每個單詞來匹配的,時間不是很理想。這道題要用到ac自動機的衍生物 fail樹 我也是做這道題才知道有這個東西 fail樹有這麼乙個結論 乙個字串出現的次數等於以它為根節點的fail樹的子樹中所有節點的cnt的和。根據這個結論,我們...

bzoj3172 單詞 AC自動機

感覺以前寫過。bzoj上不去我也不知道 跑一遍ac自動機,每乙個節點儲存一下屬於多少字串,為它的權值。然後乙個節點表示的字串在整個字典中出現的次數相當於其在fail樹中的子樹的權值的和。ac自動機不要寫掛就好了。ac 如下 include include include define n 11000...