双值Hash

简单介绍

  • Hash的应用:Hash其实就像一个加密过程,很多加密算法都会用到Hash,像GitHub中生成的token值也是Hash的结果。

  • Hash冲突:简单来说就是不同的数映射到了同一个值,防止碰撞的最有效方法就是扩大Hash值的取值空间,也就是最好选用一个大质数(具体原因参考生日悖论/生日攻击:生日攻击是一个计算机密码学中的术语)。

  • 数学原型生日问题:一个班需要多少人,能保证有两个人的生日是一样的。鸽笼原理可能会得出366人,但是实际情况远少于366。这意味着Hash碰撞的可能性远比想象的高,实际上有一个近似的公式\(\sqrt{\frac{\pi}{2}N}\)可以算出50%Hash碰撞所需要的计算次数。这个公式告诉我们Hash碰撞所需耗费的计算次数,和取值空间的平方根是一个数量级。

进入正题

双值Hash就是用两个不同的mod值来计算Hash,如果两个Hash值都相等才认为是同一个字符串,Hash冲突概率降低了很多,但是常数大,容易被卡。时间上:自然溢出法<单Hash+大质数<双Hash+大质数。

  • Hash的几个常用公式:(虽然说本题不需要用到)

    • Hash递推:

      Hash[0]=0;
      Hash[i]=(Hash[i-1]*p+s[i]-'a'+1)%mod;
    • 区间Hash值:

      Hash[L...R]=(Hash[R]-Hash[L]*p^(R-L+1)+mod)%mod;这里减法可能会溢出

使用Hash的几个需要注意的地方

  • 在复杂度允许的情况下,尽量采用多Hash(不过一般双值Hash就够)

  • 比赛时能不用自然溢出就不要(平时刷题如果用自然溢出被卡可以及时换掉,但是比赛时如果用自然溢出,OI赛制就GG了)

  • 模数用大质数这个不用说了

  • 并且进制数不要选太简单的,比如 233和 13131 这样的,尽量大一点,比如1313131和233333,太小容易被卡。

  • 以及要合理应对各种卡hash方法的最好方法就是自己去卡一遍hash,详情请参考BZOJ hash killer系列。(各位巨佬可以尝试一下hash killer 3啊233333)

例题

题目链接:

给出N个字符串,输出不同字符串的个数。

#include <iostream>
#include <cstring>
#include <algorithm> using namespace std;
typedef unsigned long long ull;
const ull mod1=212370440130137957ll;
const ull mod2=(1<<30);
const int maxn=10001;
const int base=233333;
char a[maxn];
int n;
struct node{ull x,y;
bool operator < (const node& a)const{
return a.x==x?a.y<y:a.x<x;
}
}f[maxn];
inline ull hash1(char s[]){
ull ans=0,len=strlen(s);
for(int i=0;i<len;++i)ans=(ans*base+(ull)s[i])%mod1;
return ans;
}
inline ull hash2(char s[]){
ull ans=0,len=strlen(s);
for(int i=0;i<len;++i)ans=(ans*base+(ull)s[i])%mod2;
return ans;
}
int main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%s",a);
f[i].x=hash1(a);
f[i].y=hash2(a);
//cout<<f[i].x<<" "<<f[i].y<<endl;
}
sort(f+1,f+1+n);
int ans=0;
for(int i=1;i<=n;++i){
if(f[i].x!=f[i+1].x||f[i].y!=f[i+1].y)ans++;//非相同字符串两个Hash值同时相等的概率非常小
}
printf("%d\n",ans);
return 0;
}

# 双值Hash的更多相关文章

  1. 2018-10-14普及模拟赛」Hash 键值 (hash)

    今天,带大家看一看一道思维题... Hash 键值 (hash) 题目描述 Marser沉迷hash无法自拔,然而他发现自己记不住hash键值了-- Marser使用的hash函数是一个单纯的取模运算 ...

  2. Southwestern Europe Regional Contest 2014 题解

    时间:2017/9/8 题目8/10 Rank 5/150 体会:三星的题目和国内区域赛差距大,大多数题读懂题意就能做,所以静心读题是关键,套路性太深. A: 题意:给出一个算式,算式中的数字用大写字 ...

  3. CF 494 F. Abbreviation(动态规划)

    题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...

  4. python中那些双下划线开头得函数和变量--转载

    Python中下划线---完全解读     Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用'from module import *'导入 __xxx__ 系统定义名字 __x ...

  5. 从Hash Killer I、II、III论字符串哈希

    首先,Hash Killer I.II.III是BZOJ上面三道很经典的字符串哈希破解题.当时关于II,本人还琢磨了好久,但一直不明白为啥别人AC的代码都才0.3kb左右,直到CYG神犇说可以直接随机 ...

  6. python中那些双下划线开头得函数和变量

    Python中下划线---完全解读     Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用’from module import *’导入 __xxx__ 系统定义名字 __x ...

  7. 【字符串算法1】 再谈字符串Hash(优雅的暴力)

    [字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述  [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...

  8. 字符串hash&&对字符串hash的理解

     对字符串hash的一些总结: 1,首先,我们在转化的时候,取底的时候一般是取131这些数,因为要避免不同的字符串对应相同的hash值这种情况的出现.如果卡精度的时候,我们可以采取双模数的方式尽量减少 ...

  9. 字符串hash的学习部分 可以算是模板?

    资料来自于http://www.bilibili.com/video/av7230433/ 定义这个字符串为s ①单hash hash[i] = (hash[i - 1] * p + idx(s[i] ...

随机推荐

  1. python 文件,文件夹,路径操作

    判断路径或文件os.path.isabs(...) # 判断是否绝对路径os.path.exists(...) # 判断是否真实存在os.path.isdir(...) # 判断是否是个目录os.pa ...

  2. 【做题记录】AtCoder AGC做题记录

    做一下AtCoder的AGC锻炼一下思维吧 目前已做题数: 75 总共题数: 239 每一场比赛后面的字母是做完的题,括号里是写完题解的题 AGC001: ABCDEF (DEF) AGC002: A ...

  3. POJ2689

    题目 POJ2689 Prime Distance 原题传送门 主要思路 刚看到这题,心想:不就筛个 \(\left[2,U\right]\) 的质数表出来就可以了吗?一看数据范围: \(1<= ...

  4. asyncio之异步上下文管理器

    异步上下文管理器 前面文章我们提到了上下文管理器,但是这个上下文管理器只适用于同步代码,不能用于异步代码(async def形式),不过不用担心今天我们就来讨论在异步中如何使用上下文管理器. 特别提醒 ...

  5. Chrome浏览器报错:ERR_UNSAFE_PORT

    今天用Chrome浏览器打开一个页面发现报错了:ERR_UNSAFE_PORT. 所以,去搜了一下发现Chrome浏览器是默认一些端口号为非安全端口的. 遇到这个问题建议更换端口号或者更换浏览器打开. ...

  6. 如何构建自己的docker镜像

    需求情况:springboot项目想要部署到docker里面,如何部署? 步骤如下: 1.将jar包上传linux服务器 /usr/local/dockerapp 目录,在jar包所在目录创建名为 D ...

  7. mysql数据库每个表的备份脚本

    对mysql数据库中的每张表进行按日期备份,思想是:先把每张表的表名取出取出,然后通过for循环去对每个表进行按日期备份 [root@ZFVM-APP-- backup]# vim dataname. ...

  8. JS判断与过滤的表情符号表情的方法

    一.js判断文本中是否有表情符号表情 isEmojiCharacter(substring){ for ( var i = 0; i <substring.length; i ++){ var ...

  9. strace调试跟踪程序运行状态

    查看进程调用和执行状态  :   strace  -f -F  -o debug.log  -p   PID(某个进程ID) 参考资料: http://www.itshouce.com.cn/linu ...

  10. 图解 HTTP 笔记(六)——HTTP 首部

    本章主要讲解了 HTTP 首部的结构,已经首部中各字段的用法. 一.HTTP 报文首部 上图是 HTTP 请求报文的结构. HTTP 请求报文由方法.URI.HTTP 版本.HTTP 首部字段等组成. ...