各位毒瘤大家好, 最近模拟赛考了一道trie+主席树好题, 但大家都用hash水过了这道题(包括我), 为了测试一下新搭建的HEAT OJ的hack功能, 我将继续扮演毒瘤的角色, 用毒瘤的艺术形象努力创造一个正能量的形象, 文体两开花, 弘扬中华文化, 右转去BZOJ搞了一晚上hashkiller, 回来卡了单哈希(双哈希是真滴卡不住

哈希(hash) :

利用大质数或其他对应函数把字符串转为一个正整数来快速判断字符串相等

通常可以模一个大质数或使用自然溢出

实现(例);

const int P = 1e9+7;
const int di = 1331;
hash[i] = (hash[i-1] * base + s[i]) % P;

其中\(base\), 我称之为底数, P我称之为模数, 事实上自然溢出相当于模了\(2^{64}\)

卡哈希的思想:

  1. 数学构造
  2. 随机数据(依据生日悖论

Part 1 生日悖论:

如果一个班级有23个人, 那么其中有两个人生日相同的概率超过50%

surprise 这与大部分人的直觉相违背, 所以称之为生日悖论

为什么会这样呢, 是自己的直觉不靠谱吗?

不, 我们可以考虑另一个问题, 如果一个班里有23人包括自己, 有人生日和自己相同的概率是多少?

没错, 大概为\(6%\)左右, 这是与直觉近似的, 其实我们的直觉正是把"有人生日相同"和"有人生日和自己相同"的概念相混, 实际有人生日和自己相同的概率确实很小

证明可以用排列组合开心的手玩一下

性质:

样本容量为\(n\), 超过\(50%\)概率有两个样本相同的概率为

\[1.18\sqrt{n}
\]

Part 2 卡大质数hash (1000000009) :

考虑生日攻击, 随机一个1e5大小的字符串, 询问长度为\(L\)的本质不同子串有多少个, 用大质数\(hash\)和后缀数组(也可以用自然溢出\(hash\))对拍, 输出不同子串的终止位置, 拿\(fc\)命令对比一下, 找出\(hash\)值相等的不同子串

正确性如生日悖论, 大概有超过\(50%\)的几率成功, 实际上质数不强的时候有很多相同

Part 3 卡自然溢出hash:

自然溢出\(hash\)在数据随机的情况下正确性极高, 因为它的值域很大, 很难生日攻击

考虑特殊构造:

对于底数为偶数:

构造\(aaaa\cdots aaaa\) 和 \(baaa\cdots aaaa\)两个长度相等且长度大于64的串

底数的六十四次方以上模\(P\)就会为零, \(b\)和\(a\)也会被判为相等

对于底数为奇数:

不太好卡, 要用神仙的构造方法:

设一个串\(s[]\), \(s[1] = 'a'\) 设$ |s| = strlen(s + 1)$ 为\(s\)的长度

定义$ (!s)$ 为\(s\)中的字符全部\('a'变'b', 'b'变'a',\) 当然\(s\)中只含有\('a'\)和\('b'\)两种字符

定义串\(S1 + S2\)为\(S1\)串在前\(S2\)串在后拼接起来, \(hash(s1)\) 为\(s1\)的哈希值

类似数列的, 我们定义一个"字符串列", 为一个字符串集合{\(S_n\)}, 后一个字符串可以通过前一个字符串推出

\(S_1 = "a"\)

\[S_i = S_{i-1} + (!S_{i-1})
\]

则\(S_i\)的长度为\(2^{i-1}\)

\[hash(S_i) = hash(S_{i-1}) * base^{|S_{i-1}|} + hash((!S_{i-1})) \\
= hash(S_{i-1}) * base^{2^{i-2}} + hash((!S_{i-1})) \\
hash((!S_{i-1})) = hash((!S_{i-2})) * base^{2^{i-2}} + hash(S_{i-1}) \\
hash(S_i) - hash((!S_{i-1})) = (hash(S_{i-1}) - hash((!S_{i-2}))) * base^{2^{i-2}} - (hash(S_{i-1}) - hash((!S_{i-2})))\\
hash(S_i) - hash((!S_{i-1})) = (hash(S_{i-1}) - hash((!S_{i-2}))) * (base^{2^{i-2}} - 1)
\]

希望得到 \(2^{64} | hash(S_i) - hash(!S_i)\) 设\(g_i = hash(S_i) - hash(!S_i)\)

\(g_i=g_{i-1}*(base^{2^{i-2}}-1)\) 每个 \((base^{2^{i-2}}-1)\) 都是偶数, 这使得g到第64项就就可以卡掉hash了,

但事实上12位以上就行, 因为

\[base^{2^{i-1}}-1=(base^{2^{i-2}}-1)*(base^{2^{i-2}}+1)
\]

为一个偶数乘一个偶数, 而左边的可以继续递归下去, 所以原式整除\(2^i\) 然后就结束啦

长大后, 我要当毒瘤, 爷爷奶奶可高兴了, 给我爱吃的...


毒瘤养成记1: 如何卡hash的更多相关文章

  1. 2016级算法第六次上机-F.AlvinZH的学霸养成记VI

    1082 AlvinZH的学霸养成记VI 思路 难题,凸包. 分析问题,平面上给出两类点,问能否用一条直线将二者分离. 首先应该联想到这是一个凸包问题,分别计算两类点的凸包,如果存在符合题意的直线,那 ...

  2. 2016级算法第六次上机-D.AlvinZH的学霸养成记V

    1081 AlvinZH的学霸养成记V 思路 中等题,计算几何. 这是一个排序问题,按极角排序.可以转化为叉积的应用,对于点A和B,通过叉积可以判断角度大小,共线时再判断距离. 叉积的应用.OA × ...

  3. 2016级算法第六次上机-C.AlvinZH的学霸养成记II

    1032 AlvinZH的学霸养成记II 思路 中等题,贪心. 所有课程按照DDL的大小来排序. 维护一个当前时间curTime,初始为0. 遍历课程,curTime加上此课程持续时间d,如果这时cu ...

  4. 2016级算法第五次上机-E.AlvinZH的学霸养成记IV

    1039 AlvinZH的学霸养成记IV 思路 难题,最大二分图匹配. 难点在于如何转化问题,n对n,一个只能攻击一个,判断是否存在一种攻击方案我方不死团灭对方.可以想到把所有随从看作点,对于可攻击的 ...

  5. 2016级算法第五次上机-D.AlvinZH的学霸养成记III

    850 AlvinZH的学霸养成记III 思路 难题.概率DP. 第一种思考方式:直接DP dp[i]:从已经有i个学霸到所有人变成学霸的期望. 那么答案为dp[1],需要从后往前逆推.对于某一天,有 ...

  6. nlp算法工程师养成记 目标要求

    时间规定: 2018.12.07-2018.02.15 能力养成: linux, shell python, c++(会多少算多少) tensorflow, keras, pytorch(tf优先) ...

  7. 架构师养成记--35.redis集群搭建

    前记:redis哨兵经验之谈.哨兵做主从切换可能要花费一两秒,这一两秒可能会丢失很多数据.解决方法之一是在java代码中做控制,try catch 到 链接断开的异常就sleep 一两秒钟再conti ...

  8. 架构师养成记--31.Redis的几种类型

    String类型 Redis一共分为五种基本数据类型:String.Hash.List.Set.ZSet String类型是包含很多张类型的特殊类型,并且是二进制安全的.比如对序列化的对象进行存储,比 ...

  9. 架构师养成记--15.Disruptor并发框架

    一.概述 disruptor对于处理并发任务很擅长,曾有人测过,一个线程里1s内可以处理六百万个订单,性能相当感人. 这个框架的结构大概是:数据生产端 --> 缓存 --> 消费端 缓存中 ...

随机推荐

  1. 在spring security3中使用自定义的MD5和salt进行加密

    首先看代码: <authentication-manager alias="authenticationManager"> <authentication-pro ...

  2. H3C 环路避免机制五:抑制时间

  3. linux加载和卸载模块

    模块建立之后, 下一步是加载到内核. 如我们已指出的, insmod 为你完成这个工作. 这个 程序加载模块的代码段和数据段到内核, 接着, 执行一个类似 ld 的函数, 它连接模块中 任何未解决的符 ...

  4. ES6,ES7重点介绍

    1. 字符串模板 <!--旧版拼接字符串--> var str = '我是时间:'+new Date(); <!--新版拼接字符串--> let str = `我是时间${ne ...

  5. 【50.40%】【BZOJ 4553】[Tjoi2016&Heoi2016]序列

    Time Limit: 20 Sec  Memory Limit: 128 MB Submit: 371  Solved: 187 [Submit][Status][Discuss] Descript ...

  6. "技术框架太多,多的眼花缭乱,如何在众多选择中找到自己的方向?

    "技术框架太多,多的眼花缭乱,如何在众多选择中找到自己的方向?",经常有人这么问我. 咱们从开源项目说起,可以从两个维度来对开源项目进行分类,一方面是编程语言,另一方面是应用领域. ...

  7. Qt4.5 QFrame(相当于Delphi里的TPanel,有各种凹凸方式)

    QFrame类是有框架的窗口部件的基类. QPopupMenu使用这个来把菜单“升高”,高于周围屏幕.QProgressBar有“凹陷”的外观.QLabel有平坦的外观.这些有框架的窗口部件可以被改变 ...

  8. javaweb项目添加log4j日志

    谈到我们在Java程序中经常用的日志,Log4j应该是耳熟能详了.这里先提下slf4j,英文全名是Simple Logging Facade for Java,直面意思是:Java的简单日志门面.sl ...

  9. P3225 [HNOI2012]矿场搭建 题解

    这道题挺难的,可以加深对割点的理解,还有,排列组合好重要了,分连通块,然后乘法原理(加法原理计数什么的) 传送门   https://www.luogu.org/problem/P3225 省选oi题 ...

  10. react-native-swiper使用的坑

    今天使用引入react-native-swiper组件使用轮播图时,发现报如下错误: Invarint Violation:ViewPagerAndroid has been removed from ...