太菜了,不會 AHU。
這裡介紹樹雜湊演算法。
樹雜湊
有根樹雜湊
我們怎麼快速判斷兩棵樹是否同構呢?使用樹雜湊!
我們把每棵同構樹用一個雜湊值代表。
也就是說,兩棵同構的樹用用同一個雜湊值代替。
我們可以理解為,每個雜湊值都對映著唯一的樹。
那麼怎麼計算一棵樹的雜湊值呢?我們令根節點代表的是整棵樹的雜湊值。
所以當前節點的雜湊值可以透過子樹雜湊得到。
我們知道,只要所有根節點的子樹相同,那麼這就是同構的樹。
由於子樹之間不存在順序,所以我們考慮和雜湊。
在這一步,前人經過大量挖掘,終於研製出一種很難卡的雜湊演算法:
定義轉換函式 \(g(x)\) 每個相同 的 \(x\) 都會產出一個唯一的 \(x\)
產出唯一透過異或運算即可,採用自然溢位最好。
所以,我們得到每個節點的雜湊計算通式:
\[f(x)=c+\sum\limits_{v\in E_u} g(f(v))
\]
一般 \(c=1\) 。
我覺得這是正確的,因為 \(g(x)\) 可以透過人類智慧構造出 114514 種寫法。
板子是能過的。
無根樹雜湊
上面說的所有都是有根樹。
對於無根樹,我們有兩種方案:
- 取重心為根,如果有兩個,則都計算,取值小的那個。
- 隨意取根,對於整棵樹做一次換根 dp ,然後取值最小的。
時間複雜度都是 \(O(n)\) 的,一般來說,第二種擴充性更好。