Bzoj3172 單詞(AC自動機)

2021-08-22 11:27:03 字數 1132 閱讀 3833

time limit: 10 sec  

memory limit: 512 mb

submit: 5051  

solved: 2467

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

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

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

aaaaa63

1優化:

由上述演算法可知,每個文字串(即每個單詞)在ac自動機上的每個結點,都可以使 其延fail陣列能走到的單詞 的出現次數加1

因此,可以建出fail樹,給每個單詞在ac自動機上的每個結點標號都加1(打標記),意味著其父結點中詞尾的出現次數增加1

但這裡不上溯,在fail樹上做一次dp(類似字首和)

這裡可以直接利用建立ac自動機時的佇列,從後往前,每個元素對應fail樹中的結點層數一定是從高到低的

處理重複單詞:

若單詞i與j相同(i

(

i

,就用鍊錶把j接到i的後面,ac自動機的詞尾結點上記錄該詞第一次出現的序號,即可

#include

#include

#include

#include

#include

#include

using

namespace

std;

const

int n=1000005;

int ch[n][30],val[n],lastnum[n],sum[n],q[n],tot=0,ans[n],f[n];

char st[n];

void insert(int t)

if (val[u]==0) val[u]=lastnum[t]=t;

else lastnum[t]=val[u];

}void pre()

head++;

}for (int i=tail-1; i>=0; i--)

}int main()

miao~~~

BZOJ 3172 單詞 (AC自動機)

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

bzoj3172 單詞 AC自動機

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

bzoj3172 單詞 AC自動機

有n個單詞組成了一篇文章,求每個單詞在這篇文章中出現了多少次。多個字串匹配的問題,建立ac自動機。如果某個單詞在i節點出現了,那麼在i節點fail指標所指節點也出現過。code include include using namespace std const int max n 1000005 s...