字符串哈希
字符串Hash的目的是,如果我们判断两个字符串是否相等,就直接看它们对应的hash值是否相等。从而达到,子串的Hash值的时间为 O(1),进而可以利用“空间换时间”来节省时间复杂的。
一定不能使用hash来定义数组
自然溢出:
unsigned long long h[n];
h[i] = h[i-1] * p + ss[i];
利用unsigned long long 的范围自然溢出,相当于自动对pow(2,64) - 1 取模;
单Hash方法:
hash[ i ] = hash[ i − 1 ] *p + s [ i ] % mod
其中p 和 mod 均为质数,且有 p < mod
对于此种Hash方法,将p和mod尽量取大即可,这种情况下,冲突的概率是很低的
双Hash方法:
h a s h 1 [ i ] = ( h a s h 1 [ i − 1 ] ) ∗ p + i d *( s [ i ] ) % mod
h a s h 2 [ i ] = ( h a s h 2 [ i − 1 ] ) ∗ p + i d * ( s [ i ] ) % mod2
hash结果:< h a s h 1 [ n ] , h a s h 2 [ n ] >
某一个区间的hash值求法(假设字符串从1开始):
hs[0] = 0;
hs[1] = hs[0] * p + s[1];
hs[2] = hs[1] * p + s[2] = hs[0] * p * p + s[1] * p + s[2];
hs[3] = hs[2] * p + s[3] = hs[0] * p * p * p + s[1]pp + s[2] * p + s[3];
hs[4] = hs[3] * p + s[4] = hs[0] * p * p * p * p + s[1] * p * p * p + s[2] * p * p + s[3] * p + s[4];
区间公式为:hs[r] - hs[l-1] * p ^ (r - l + 1);
预处理p的n次方可以节约时间;
hx[i]=hx[i-1]*p+s[i];
pre[i]=pre[i-1]*p;//预处理