字符串哈希
使用场景
比较字符串字典序大小时需要遍历两个字符串的长度
但是仅关注两个字符串是否相同时,比较时O(字符串长度)的复杂度显得有些奢侈。
把字符串映射到数字可以很好的解决这个问题,和某一字符串对应的数字就叫组字符串的哈希码。
如何实现
Hash[i]为字符串前i位的哈希码
idx(i)为字符串第i位字母对应的数字(idx可以等于 s[i] - ‘a’ + 1,或者s[i]的ASCII码)
p 和 mod 为两个不相同的质数
单哈希法
- Hash[i] = (Hash[i - 1] * p + idx(i)) % mod
双哈希法
使用两个不同的mod值计算出的哈希值对应一个字符串,可以使得字符串的哈希值几乎不可能重复
-
Hash1[i] = (Hash1[i - 1] * p + idx(i)) % mod1
-
Hash2[i] = (Hash2[i - 1] * p + idx(i)) % mod2
-
Hash[i]:<Hash1[i],Hash2[i]>
字符串哈希的性质
虽然预处理时也需要O(字符串长度)的复杂度,但是预处理字符串之后,其任意字串的哈希值可以O(1)求出
- Hash[l, r] = (Hash[r] - Hash[l - 1] * p^(r - l + 1) + mod) % mod
质数的选择
例题
http://codeforces.com/gym/102803/problem/C
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 8e5 + 5;
const int mod = 1e9 + 7;
const int base = 131;
char s[maxn];
ll h[maxn], p[maxn];
ll getHash(int l, int r)