字符串哈希
十进制数1234=1103+2102+3*10+4对于字符串”abcd”我们将它看做p进制的数,那么hash=’a’*p3+’b’*p2+’c’*p+’d’。但是如果字符串足够长的话,long long是存不下的,所以还需要取模。
字符串哈希的两个问题
1、任意字符不能等0。假设字符a=0,那么对于字符串a和aa的hash值都会等0,就会发生冲突。
2、不同的字符串的hash值取模后可能会相等,就是发生冲突了。选择合理的p和mod可以降低冲突的概率,p一般取131、13331或者2333,mod一般取1e9+7,1e9+9或者264。虽然说冲突概率能降低,但是还是可能会发生冲突,可以使用双哈希:模数选择两个不同的质数分别对hash值取模,只有两个hash值都相等的话才判定字符串相等。
//单哈希
Hash[0]=0;
for(inti=1;i<=n;i++)
Hash[i]=(Hash[i-1]*p+s[i])%mod;//前i个字
//双哈希
Hash1[0]=Hash2[0]=0;
for(inti=1;i<=n;i++)
{
Hash1[i]=(Hash1[i-1]*p+s[i])%mod1;
Hash2[i]=(Hash2[i-1]*p+s[i])%mod2;
}
//求区间[l,r]的子串的hash值
((hash[r]-hash[l-1]*pow(p,r-l+1))%mod+mod)%mod;