字符串哈希

定义

定义一个把字符串映射到整数的函数 ,称为 Hash 函数。我们希望这个函数可以方便地判断两个字符串是否相等。

核心思想

将字符串视为一个 进制数,对一个大质数 取模:

例如字符串 的哈希值为

参数常见取值说明
基数 131, 233, 91138233大于字符集大小的质数
模数 , 大质数,双哈希用两个不同模数
自然溢出unsigned long long,效率高但有被卡风险

子串哈希 O(1) 查询

预处理前缀哈希 ,则子串 的哈希值为:

using ull = unsigned long long;
constexpr int B = 131;
constexpr ull M = 1e9 + 7;
vector<ull> h(n + 1), pw(n + 1);
pw[0] = 1;
for (int i = 1; i <= n; i++) {
    pw[i] = pw[i-1] * B % M;
    h[i] = (h[i-1] * B + s[i-1]) % M;
}
auto get = [&](int l, int r) {
    return (h[r] - h[l-1] * pw[r-l+1] % M + M) % M;
};

双哈希

用两个不同模数分别计算,两个哈希值都相等才认为字符串相同,将冲突概率降到极低。

哈希的冲突

  • 生日悖论: 当比较的字符串数量 增大时,冲突概率平方级上升
  • ,其中 为值域大小
  • 自然溢出 为偶数时可被构造碰撞
  • 大模数 可用双哈希抵御

应用场景

  • 字符串匹配(O(n+m) 预处理 + O(1) 比较)
  • 允许 k 次失配的匹配(哈希 + 二分失配位置)
  • 最长回文子串(正反哈希 + 二分)
  • 不同子串数量
  • 最长公共子串(二分长度 + 哈希集合)

推荐练习题

平台编号名称
洛谷P3370字符串哈希(模板)
洛谷P2757等差数列
Codeforces1200ECompress Words

相关链接

内容来源:经本地化改造的 OI-wiki 字符串哈希章节。详细推导见 OI-wiki

多平台练习

| 洛谷 | 本题单 | 竞赛基础 |
| POJ (北大) | PKU JudgeOnline | 经典题目,适合巩固 |
| HDU (杭电) | HDU OJ | 暑期多校训练 |
| Codeforces | Codeforces | 国际竞赛,适合提升 |