AcWing算法基础课 哈希


整数哈希:

一般可以用取模的方式,模的数(数组长度)最好取质数且离2的幂尽可能远

哈希冲突可以用拉链法和开放寻址法解决

拉链法可以用链表进行模拟,插入时在哈希寻址处的链表头结点插入

开放寻址法则直接向后找(经验值,数据长度一般要开到题目数据范围的2-3倍),利用find函数找到数据的位置或应该插入的位置。

字符串哈希:可以用来判断两个(子)字符串是否相等(映射到相等的哈希值)

字符串前缀哈希法

将字符串看做p进制的数,A->1,B->2...Z->26,或直接用字符的ASCII码

计算出字符串的值,ABCD->1*p^3+2*p^2+3*p^1+4*p^0

在取模转化为较小的数(同整数哈希)(1*p^3+2*p^2+3*p^1+4*p^0)%Q,转化为0~Q-1的数。

注意,一般不能把某个字母映射成0,否则,若A->0,A=AA=AAA=0

 经验值,p=131或13331,Q=2^64,此时哈希基本不会出现冲突,用unsigned long long存储所有的h,则溢出就相当于mod Q。

预处理,先对字符串的所有前缀计算出哈希值,则可以计算出所有子段的哈希

h[i]表示0-第i个字符的哈希(下标从1计)

h[0]=0表示没有字符,

h[i]=h[i-1]*p+str[i]

可以预处理p^(i),令p[0]=1,p[i]=p[i-1]*P,其中P=131或13331

计算哈希值:

h[L~R]=h[R]-h[L-1]*p^(R-L+1)