哈希冲突
如果使用普通哈希,可能会发生哈希值重复,称为哈希冲突
假设我们用哈希算法,通过哈希值进行了n次比较,每次比较错误率为1/M,则总错误率为
1
−
(
1
−
1
M
)
n
\def\sqr#1{#1^n} \sqr{1-(1-\text{\(\frac 1 M\)})}
1−(1−M1)n
错误率M=1/p,当n=1e7时,带入得知总错误率为1%,一般情况下有20组数据,错误率为20%
出题人往往阴险狡诈,设置特殊的数据,让哈希冲突的概率提高。
如何解决呢?
双哈希
常用模数1e9+7,998244353,
底数:128,131,26,31
代码:
typedef long long ll; // 定义 long long 别名为 ll
struct HASH { // 定义结构体 HASH
ll sed, mod, h[N], pw[N]; // 成员变量包括 sed, mod, h 数组和 pw 数组
void init(ll ser_in, ll mod_in) { // 初始化函数,接收两个参数 ser_in 和 mod_in
sed = ser_in, mod = mod_in; // 将参数赋值给 sed 和 mod
pw[0] = 1; // 初始化 pw[0] 为 1
for (int i = 1; i < N; i++) // 循环计算 pw 数组的值
pw[i] = pw[i - 1] * sed % mod;
}
void make(string s) { // 计算哈希值的函数,接收一个字符串参数 s
h[1] = s[1] % mod; // 初始化 h[1] 为 s[1] 对 mod 取余
for (int i = 2; i <= n; i++) // 循环计算字符串 s 的哈希值
h[i] = (h[i - 1] * sed % mod + s[i]) % mod;
}
ll get(int l, int r) { // 获取子串哈希值的函数,接收两个整数参数 l 和 r
return (h[r] - h[l - 1] * pw[r - l + 1] % mod + mod) % mod; // 返回子串 [l, r] 的哈希值
}
};