之前很喜歡用鍊錶寫ac自動機,覺得很適合自己的理解。一直都沒有接觸陣列的寫法。。然而稍微難一點的ac自動機的題,大佬們都是用陣列寫的,搞的我也看不懂大佬的思路。。
所以覺得重新學習一下陣列的寫法,但是收穫還是有的,又學習了一些關於ac自動機的小優化。
struct acauto
void insert(string s )
root = next[root][id] ;
}num[root]++ ;
}void get_fail()
}while (!que.empty())
else next[tmp][i] = next[fail[tmp]][i] ;}}
}int query (string s )
}return ans ;
}}ac ;
小優化:
1.類似於路徑壓縮。
if (next[tmp][i])
else next[tmp][i] = next[fail[tmp]][i] ;
此步操作使得在比較時省去了 while 迴圈。2.字尾連線:如果沒有匹配,直接進入 fail 的匹配之中。
void get_fail()
}while (!que.empty())
else next[tmp][i] = next[fail[tmp]][i] ;}}
}
此處我們的 last 大概可以理解為乙個超級 fail.因為我們只有到根節點時才會重新匹配乙個字母
所以我們此時直接記錄乙個last ,直接結束當前匹配過程.
直接省去原 fail 指標到可以匹配的節點之間的距離。
這樣的做法可以節省時間, 不過需要注意的是記憶體的限制!3.樹形dp優化。
樹形dp優化的是查詢部分.首先我們可以發現, fail 指標是絕對滿足樹形結構的.
顯而易見,每個點的 fail 都僅指向乙個乙個節點。
但是還沒遇到此類優化問題,所以本人也不會。。。
AC自動機(簡單版)
覺得ac自動機怪簡單是怎麼回事?可能題太裸了 網上講ac自動機和tire樹講的比我好的dalao數不勝數,我就不多贅述了,權當是掛個板子吧。其實char和strlen還是挺好用的。include include include using namespace std struct tire tr 1...
模板 AC自動機(簡單版)
有 nn 個由小寫字母組成的模式串以及乙個文字串 tt 每個模式串可能會在文字串中出現多次。你需要找出哪些模式串在文字串 tt 中出現的次數最多。trie樹打錯了,改了我幾個小時。其實,ac自動機只是在trie樹上做kmp罷了。建樹 不多說 構建fail指標。trie樹的失配指標是指向 沿著其父節點...
模版 AC自動機(簡單版)
這是一道簡單的ac自動機模版題。用於檢測正確性以及演算法常數。為了防止卡oj,在保證正確的基礎上只有兩組資料,請不要惡意提交。給定n個模式串和1個文字串,求有多少個模式串在文字串裡出現過。輸入格式 第一行乙個n,表示模式串個數 下面n行每行乙個模式串 下面一行乙個文字串。輸出格式 乙個數表示答案 輸...