国家集训队2007论文集1.杨弋《Hash在信息学.docVIP

国家集训队2007论文集1.杨弋《Hash在信息学.doc

  1. 1、本文档共12页,可阅读全部内容。
  2. 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
  3. 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  4. 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  5. 5、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  6. 6、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  7. 7、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  8. 8、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
Hash在信息学竞赛中的一类应用 【】 那么,模式串Y的Hash值就可以轻松地求出。记待匹配串X从第i个字符开始的长度为M的子串为Si,则不难发现f(Si+1)和f(Si)的关系: 换个角度,如果不考虑mod q,这个函数就是把字符串看作一个p进制数求出的值,这样,Xi+1就是Xi “左移”一位,然后去掉最前面一位,再加上右面新进来的一位得到的。因此上面的递推公式也是显然的。 有了这个递推公式,不难在线性时间内求出X的所有长度为M的子串的Hash值。 现在把问题扩展到高维的情况。不难发现要计算的Hash值的个数仍然不超过N个,可见,只要有合适的递推方法,仍然可以在线性时间内求出所有子矩阵的Hash值。事实上,一个M1行,M2列的子矩阵可以被看作是M2个“竖条”组成的一个串。我们可以先把每个长度为M1的“竖条”计算出一个Hash值,然后再计算二维情况的Hash值。 需要注意的一点是,在计算一维的Hash值(“竖条”的Hash值)和计算二维的Hash值时使用的b值不能一样,不然不难想到下面反例: 它们并不相同,但是Hash的结果肯定一样。这就违背了使用Hash的初衷。因此,在第一维的计算和第二维的计算中要使用不同的p值。 二维情况时,求出所有长度为M1的“竖条”所需要花费的时间是O(N)的,然后把这些竖条的Hash值看作“字母”计算横向的Hash值(即各个子矩阵的Hash值),所花费的时间也是O(N)的。总时间复杂度仍然是O(N)的。 二维情况的Hash函数为(len1(S)和len2(S)分别表示S在两个维度上的大小): 类似地,记待匹配矩阵X从第i1行,第i2列为左上角的M1行,M2列的子矩阵为,我们有递推式: 式中和都是一维情况下的Hash值,即预先计算出的“竖条”的Hash值。 扩展到k维情况,则不难想到,先算出所有尺寸为M1×M2×…×Mk-1的子数组的Hash值,再使用类似上面的办法把这些尺寸为M1×M2×…×Mk-1的子数组的Hash值看作一个个字符而使用Rabin-Karp的Hash函数计算出各个尺寸为M1×M2×…×Mk的子数组的Hash值。可见,需要k轮计算就可以算出所有尺寸为M1×M2×…×Mk的子数组的Hash值,时间复杂度为O(kN+M)。 k维时的Hash函数: 类似地可以推出递推式 如果没有最后的mod q操作,那么这个Hash函数可以理解成一个进制转换,当每次的p都取得比当时的字符集还要大的时候,只要Hash值不同就一定能确定内容不同。但是事实上计算出来的Hash值就会大到使这个算法没有意义的程度(比较这个“Hash值”的速度不会比直接比较更快),因此取余是必须的。 一个理想情况下的Hash函数,如果能产生S种不同的值,那么对两个不一样的子数组算出一样的值的可能性就只有1/S。我们的Hash函数当然未必能达到理想情况,但是由“1/S”这个式子不难想到,加大S就能有效地减少判错的可能性。并且还能得出另一个结论:如果一个Hash函数的精确程度不够,只需要再计算一个与之不同的Hash函数,就可以有效地提高正确率!当然,在本题中,时间复杂度已经近似于(因为毕竟这个Hash函数不是理想的Hash函数)O(kN+N*(1/S)*M)了。S只要大小不比N/k小,后一项就不是时间复杂度的瓶颈了,也没有必要在这方面下太大功夫。反而,如果计算多个Hash函数,会显著增加算法的常数。 关于p和q的取值,由于可以理解成一个p进制的转换,再对q取余,应当在范围允许的情况下尽量避免冲突,建议: p不宜过小,不然很容易出错。 q可以取一个质数,然后p选取一个能使对于所有1至p-2的i,pi mod q≠1。 这个Hash函数不但可以这样滚动计算,也可以采用分段,分块,线段树等办法计算和维护,具体的一些办法可以参见后面的一些例题。 例题2 Equal squares (Ural 1486) 题目大意 在一个N×M的字符矩阵中找到两个相同的子正方形矩阵(可以相交),并使找到的两个子正方形矩阵的边长尽量大。 算法分析 有了例题1的经验,在面对本题的时候不难想到,二分查找正方形的边长,然后使用一个Hash表来判断该边长是否可行。Hash函数与例题1的二维情况一致。时间复杂度是O(NMlog(N*M))的。 但是不幸的是,本题时间限制很严,这样做的程序依然会超时。最后在使用一个看上去有点冒险的改动之后,终于通过了本题:直接检查是否产生了相同的Hash函数,如果存在相同的Hash函数,则认为该边长可行,否则即认为它不可行。 这道题目就这样通过了,但是这样的改动是不是太冒险了一点呢?事实上,两个子正方形的内容不同而Hash值相同的可能性很小。所以,一般情况下我们可以认为,如果Hash值相同,则原内容相同。 这里还有一个问题:Hash表存放

文档评论(0)

185****7617 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档