2024.3.26 哈希
哈希是把一个序列映射成一个数字
令这个序列为 \(a\), 最大数字为 \(b - 1\), 长为 \(n\)
这个数字
\[a_1 \cdot b^{n - 1} + a^2 \cdot b^{n - 2} \dots a_n \cdot b^{0}
\]
这就是这个序列的 \(hash\) 值, 不过这个数字比较大, 所以需要模上一个数 \(p\)
\(hash\) 有什么好处\(?\) \(O(1)\) 比较两个序列是否相同, \(O(\log n)\) 二分查找以 \(l, r\) 开头的最长公共前缀
有些序列虽然不同,但是 \(hash\) 在取模意义下相同, 如 \(4 \equiv 11 \pmod 7\)
如果模数为 \(10^9 + 7\), 有 \(10^5\) 个元素, 发生这种情况的概率极大, 详见生日悖论 。
如何避免这些麻烦了, 这里解释两种解决方法, 可以大大减低概率, 不过还是能被特殊数据 \(hack\)。
-
加大模数, 推荐 \(10^{18} + 3\)
-
用多哈希
- 就是节录多个不一样的 \(b, p\) 只要所以的 \(b, p\) 都在取模意义下相等, 才算它们相等