目錄
- [學習筆記 #5] 雜湊
- 前言
- 雜湊表
- 過渡:用雜湊解決判定性問題
- 不知道歸到哪裡去的技巧
- 集合雜湊
- Sum Hashing
- Xor Hashing
- 序列雜湊
- 樹雜湊
- 資料結構維護雜湊值
- 參考
[學習筆記 #5] 雜湊
下面 [ ] 起來的是我還不確定的。
前言
從今年暑假到現在(2024.11.13),考了多少道雜湊,我一道都沒場切。前年 CSP-S T3 星戰沒想出雜湊做法,去年 CSP-S T2 又沒想出雜湊做法。滿滿的黑歷史……
早就想總結了,沒時間。今天忍不住了。
雜湊表
- 雜湊表和下面說的雜湊應該不是一回事。
- 概括:縮小範圍。可以用來儲存雜湊值。
- 具體實現:
- 當集合 \(A\) 較大時,用一個函式 \(f : A \rightarrow B\) 把 \(A\) [對映] 到一個較小的集合 \(B\)。
- 查詢時給出 \(B\) 中的元素,對應回 \(A\) 中的元素。
- 但是 \(B\) 中的一個元素可能對應 \(A\) 中的多個元素,即雜湊衝突(或稱雜湊碰撞)。
- 兩種解決方法:
- 讓 \(B\) 中的每個元素掛一串(\(A\) 中的)元素。查詢時遍歷這一串。
- 讓 \(B\) 中的每個元素只對應一個(\(A\) 中的)元素。那麼每新增一個(\(A\) 中的)元素時,如果對應的(\(B\) 中)元素沒有對應元素,就對應上,否則接著找,直到找到一個還沒對應的,對應上。
- 兩種解決方法:
- 實際使用:
- 可以用 map 或 unordered_map。map 帶 \(\log\),但 unordered_map [[可能會被卡]]。
- 可以用 pb_ds 裡的雜湊表。
過渡:用雜湊解決判定性問題
- 接下來的雜湊用於解決 判定性問題。
- 採用雜湊的原因:常規方式難以判定。
- 方法:
- 我們找 充分條件或必要條件(不是充要條件) 來判定,使用雜湊來簡化問題。
- 透過隨機和多次判定來降低錯誤機率。
- 可以從原命題或 [[原命題的否定]] 兩方面考慮。
- 要 判斷是否是某種情況,就要先選擇雜湊的方式(要有針對性),再得到這樣雜湊的話這種情況的值是多少或是什麼情況,最後判斷真實的雜湊值是否滿足條件。
不知道歸到哪裡去的技巧
- 四次方([可能] 要取模)。[使雜湊值更離散。]
- 雙雜湊。
- 多次雜湊。
集合雜湊
-
透過運算的交換律來 [表現] 集合的 [無序性]。
-
可以轉化為序列雜湊:
-
方法一:
- 對集合中每個值,記錄它的出現次數,記到一個序列(桶)上(給值固定了順序)。
- 可重集:就是這樣。
- 不是可重集:出現次數是 \(0\) 或 \(1\)。
- 對這個序列跑序列雜湊。
- 對集合中每個值,記錄它的出現次數,記到一個序列(桶)上(給值固定了順序)。
-
方法二:
- 對集合排序(規定某種順序,不一定從小到大),跑序列雜湊。
-
Sum Hashing
- 雜湊值表示整個集合。
- \(h(S) = \sum _ { x \in S } h' ( x )\)。
- \(h'\):對每個 \(x\) 賦一個隨機值(相同的 \(x\) 賦的值相同)。
- 一個性質——判斷集合中每個數的出現次數是否都是 \(k\) 的倍數(出現次數為 \(0\) 也可以):
- 求和有對取模很友好的性質:如果一個數值的出現次數 \(\bmod k = 0\),那麼它的雜湊值加起來 \(\bmod k\) 也為 \(0\)。如果每個數值的雜湊值之和 \(\bmod k = 0\),那麼整個集合的雜湊值(每個數的雜湊值加起來,即每個數值的雜湊值之和加起來)就也 \(\bmod k = 0\)。因此原命題能推出 Sum Hashing 的值 \(\bmod k = 0\),那麼後者就是前者的必要條件。
- 看 Sum Hashing 的值 \(\bmod k\) 是否為 \(0\)。
- 如果不為 \(0\) 則說明集合中 每個數的出現次數都是 \(k\) 的倍數 一定不成立。
- 如果為 \(0\) 則說明 ~ 可能成立。
- [蒙特卡羅判定]。
- 隨機較多遍之後錯誤率就小到可以接受了。
- 題、錯誤率分析見:CF1746F Kazaee。
Xor Hashing
- 二進位制 Xor Hashing [較常見]。
- \(k\) 進位制 Xor Hashing。
- 每一位分別相加,不進位,分別對 \(k\) 取模。
- 雜湊值 一般 不表示整個集合,只表示每個元素出現次數 \(\bmod k\) 是否為 \(0\)。
- 如果集合中每個元素的出現次數都 \(\leq k\),Xor Hashing 表示的就是整個集合。
- 本質:
- 把很多遍 取模的 Sum Hashing(就是上面寫的 Sum Hashing 的“一個性質”部分)壓到一起跑。因為每一位是獨立的,每一位都相當於一次取模的 Sum Hashing。
- 錯誤率:
- 二進位制 Xor Hashing 的話,在 [[int 或 long long]] 範圍內隨機,[一般] 這樣跑一遍的錯誤率就剛好小到可以接受了。
- 相比 Sum Hashing 的優勢:
- (二進位制 Xor Hashing)二進位制壓縮,去掉了跑很多遍帶的大概一隻 \(\log\)。
- 異或性質優美,有時有妙用。(下面是二進位制的,[更高的] 進位制我不知道)
- 重複直接消掉:
- 樹上簡單路徑的異或和:直接算到根的異或和,異或起來即可。
- [異或線性基]。(我還不清楚正確率)(咕咕咕)
- 重複直接消掉:
序列雜湊
- 把下標加入計算中,從而 [表現] [有序性]。
- 字串雜湊。(多項式雜湊。)
- 作用:判定相等。
- 可以預處理 Base 的冪來 \(O(1)\) 取出一段的雜湊值。
- 雙雜湊。
樹雜湊
還不會嗚嗚嗚。
資料結構維護雜湊值
- 雜湊表。
- 其他資料結構。
咕咕咕。
以後來放題。
參考
- 雜湊:從入門到入土 - 題單 - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)
- 雜湊(雜湊,Hash)入門 - 題單 - 洛谷 | 電腦科學教育新生態 (luogu.com.cn)
2024.11.13