hash——operator_

文章介绍了哈希的基本概念,强调其用于快速比较和O(1)时间复杂度的特性。分别讲解了数值哈希、数组和字符串哈希的计算方法,包括子串哈希的求解。接着探讨了二维数组哈希的算法,以及如何处理子矩阵的哈希值。最后提到了树哈希的各种算法设计,特别是针对无权树和有权树的不同处理方式。
摘要由CSDN通过智能技术生成

0.哈希概述

核心:设计一个算法,使得要哈希的东西在一定程度上一一对应为一个数值,一般是通过取模实现,从而做到 O ( 1 ) O(1) O(1) 比较,或者是支持减法,从而做到 O ( 1 ) O(1) O(1) 求任意一个东西的哈希值。

一般是用于快速比较。

哈希的取模,可以使用自然溢出(即 unsigned long long超过范围自动取模),或者手动取模。

你要知道,因为哈希是基于取模的,所以对着代码还是可以卡的。自然溢出比较方便,而且速度比一般取模略快,但可能被卡,手动取模相对较烦,但不易被卡(因为模数是自定的),不过你也可以自定义一种数据类型来自动取模。

要做到几乎不被卡,可以使用双哈希(即使用不同的模数哈希两遍)。

1.数值哈希

一般的算法是: h a s h = a   m o d   M hash=a\bmod M hash=amodM

只要 M M M 选的合适就 OK 。

2.数组、字符串哈希

算法是: h a s h i = ( v ( a i ) + h a s h i − 1 ∗ b a s e )   m o d   M hash_i=(v(a_i)+hash_{i-1}*base)\bmod M hashi=(v(ai)+hashi1base)modM

其中的 v ( ) v() v() 是贡献的计算函数,数组就是 v ( a i ) = a i v(a_i)=a_i v(ai)=ai

求子串: h a s h ( l , r ) = ( ( h a s h r − h a s h l − 1 ∗ b a s e r − l + 1   m o d   M )   m o d   M + M )   m o d   M hash(l,r)=((hash_r-hash_{l-1}*base^{r-l+1}\bmod M)\bmod M+M)\bmod M hash(l,r)=((hashrhashl1baserl+1modM)modM+M)modM

预处理一下 b a s e i   m o d   M base^i\bmod M baseimodM 即可。

3.二维数组哈希

算法是: h a s h i , j = ( h a s h i − 1 , j ∗ b a s e 1   m o d   M + h a s h i , j − 1 ∗ b a s e 2   m o d   M − h a s h i − 1 , j − 1 ∗ b a s e 1   m o d   M ∗ b a s e 2   m o d   M + M )   m o d   M hash_{i,j}=(hash_{i-1,j}*base1\bmod M+hash_{i,j-1}*base2\bmod M-hash_{i-1,j-1}*base1\bmod M*base2\bmod M+M)\bmod M hashi,j=(hashi1,jbase1modM+hashi,j1base2modMhashi1,j1base1modMbase2modM+M)modM

求子矩阵: h a s h ( x 1 , y 1 , x 2 , y 2 ) = ( h a s h r x , r y − h a s h l x − 1 , r y ∗ b a s e 1 r x − l x + 1   m o d   M − h a s h r x , l y − 1 ∗ b a s e 2 r y − l y + 1   m o d   M + h a s h l x − 1 , l y − 1 ∗ b a s e 1 r x − l x + 1   m o d   M ∗ b a s e 2 r y − l y + 1   m o d   M + M ∗ 2 )   m o d   M hash(x1,y1,x2,y2)=(hash_{rx,ry}-hash_{lx-1,ry}*base1^{rx-lx+1}\bmod M-hash_{rx,ly-1}*base2^{ry-ly+1}\bmod M+hash_{lx-1,ly-1}*base1^{rx-lx+1}\bmod M*base2^{ry-ly+1}\bmod M+M*2)\bmod M hash(x1,y1,x2,y2)=(hashrx,ryhashlx1,rybase1rxlx+1modMhashrx,ly1base2ryly+1modM+hashlx1,ly1base1rxlx+1modMbase2ryly+1modM+M2)modM

同样预处理一下 b a s e 1 i   m o d   M base1^i\bmod M base1imodM b a s e 2 i   m o d   M base2^i\bmod M base2imodM 即可。

(也可以选择纵向哈希一遍,再横向哈希一遍,结果一样)

4.树哈希

前面写的是 设计一个算法,上面好像都没有设计,所以它来了。

树哈希的算法很多,旨在避免被卡。

什么千奇百怪的方法都有,比如无权树有:
h a s h u = ( s i z e u ∗ ∑ i = 1 i < s i z e u ( h a s h v ( 哈希值排名第 i 的儿子 ) ∗ b a s e i − 1   m o d   M ) )   m o d   M hash_u=(size_u*\sum_{i=1}^{i<size_u}(hash_{v(哈希值排名第i的儿子)}*base^{i-1}\bmod M))\bmod M hashu=(sizeui=1i<sizeu(hashv(哈希值排名第i的儿子)basei1modM))modM

h a s h u = 1 + ∑ v 是 u 的儿子 ( h a s h v ∗ p r i m e s i z e v   m o d   M )   m o d   M hash_u=1+\sum^{v是u的儿子}(hash_v*prime_{size_v}\bmod M)\bmod M hashu=1+vu的儿子(hashvprimesizevmodM)modM

h a s h u = b a s e 1 ∗ ( ⨁ v 是 u 的儿子 ( h a s h v ∗ b a s e 1 s i z e v   m o d   M ) + b a s e 2 )   m o d   M hash_u=base1*(\bigoplus\limits^{v是u的儿子}(hash_v*base1^{size_v}\bmod M)+base2)\bmod M hashu=base1(vu的儿子(hashvbase1sizevmodM)+base2)modM

有权树的话,设计一个能把权值考虑进去的算法即可。

我不知道能不能设计出一个可减的哈希,应该是行的但我不会

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值