转载:
整体思路整理:
注意点:
1、尽量不要映射成0,因为假如一个字母A映射成0,那么AA或者AAA它们的映射也都是0
2、p的进制我们习惯取131或者13331,Q=2^64,这样我们就可以假定不会发生冲突。
代码:
核心思想:将字符串看成P进制数,P的经验值是131或13331,取这两个值的冲突概率低
小技巧:取模的数用2^64,这样直接用unsigned long long存储,溢出的结果就是取模的结果
typedef unsigned long long ULL;
ULL h[N], p[N]; // h[k]存储字符串前k个字母的哈希值, p[k]存储 P^k mod 2^64
// 初始化
//求p的r-l+1次方
p[0] = 1;
for (int i = 1; i <= n; i ++ )
{
h[i] = h[i - 1] * P + str[i];
p[i] = p[i - 1] * P;
}
// 计算子串 str[l ~ r] 的哈希值
ULL get(int l, int r)
{
//这里的p[r-l+1]相当于乘上p的r-l+1次方
return h[r] - h[l - 1] * p[r - l + 1];
}