很久没更新了,这段时间比较忙
今天写的内容,大概是数据结构,动态规划,数学问题,计算几何,图论,搜索算法,以及一些乱七八糟的东西
这些都不讲
今天只写一个东西——就是hash
所谓hash 这是一个万能的存储方式,任何东西都可以用hash存储。
比如字符串。
我们将字符串看成一个K( K ≥ |α| )进制的大整数,再将这个大数对某个数取模作为它的hash值,这个模数取多少都可以(不要太小且越大越好),可以是你自己的生日,也可以是大家见了很多次的数字——1000000007。
在比较两个字符串是否相同时,我们只需要比较它们的hash值是否相同,牺牲O(n)的预处理时间,做到每次O(1)的比较时间。
有人会问了,比如我们取1000000007,那么1和1000000008的hash值岂不是一样?
其实啊,它们的hash值确实一样
我们可以用多个hash来避免冲突,比如我们加一个2,那么在1和1000000008的第一个hash值相等时,我们就比较第二个hash值。
甚至第三个,第四个。。。
接下来介绍一下hash killer系列题目(题解均由成都石室中学wuvin大佬的ppt提供)
hash killer 1:
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3097
自然溢出显然可以被卡。
尝试构造两个不同的串对应的hash值相同。
如果进制hash的基数base是偶数,那么字符串长度超过64即可卡掉。
如果进制hash的base是奇数:
若hash(str1) % 264 = hash(str2)% 264
( hash(str1) – hash(str2) ) % 264 = 0
令01字符串S[i] = S[i-1] + not(S[i-1]) , S[0] = ‘0’
定义h(x) = hash(S[x]),hn(x) = hash(not(S[x]))
h(i) – hn(i) = h(i-1) * base2^(i-1) + hn(i-1) - hn(i-1) * base2^(i-1) – h(i-1)
= (h(i-1) – hn(i-1)) * (base2^(i-1)-1)
Base是个奇数,basek-1一定是个偶数
例 31-1 = 2 (21), 32-1 = 8 (22), 34-1 = 80 (23)
Base2^(i-1) – 1 % 2i
= Base0 – 1 % 2i (欧拉定理)
= 0
所以说,自然溢出会把S[i]和not(S[i])判定成同一个字符串(i ≥ 11)
hash killer 2:
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3098
根据生日悖论
令N-L ≈ 105 然后输出一个随机串就可以了
hash killer 3:
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3099
killer3嘛:纯靠运(nai)气(xin)
因为
如果submit到10^8次应该就有个人过了。