# 双值Hash
双值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的更多相关文章
- 2018-10-14普及模拟赛」Hash 键值 (hash)
今天,带大家看一看一道思维题... Hash 键值 (hash) 题目描述 Marser沉迷hash无法自拔,然而他发现自己记不住hash键值了-- Marser使用的hash函数是一个单纯的取模运算 ...
- Southwestern Europe Regional Contest 2014 题解
时间:2017/9/8 题目8/10 Rank 5/150 体会:三星的题目和国内区域赛差距大,大多数题读懂题意就能做,所以静心读题是关键,套路性太深. A: 题意:给出一个算式,算式中的数字用大写字 ...
- CF 494 F. Abbreviation(动态规划)
题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...
- python中那些双下划线开头得函数和变量--转载
Python中下划线---完全解读 Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用'from module import *'导入 __xxx__ 系统定义名字 __x ...
- 从Hash Killer I、II、III论字符串哈希
首先,Hash Killer I.II.III是BZOJ上面三道很经典的字符串哈希破解题.当时关于II,本人还琢磨了好久,但一直不明白为啥别人AC的代码都才0.3kb左右,直到CYG神犇说可以直接随机 ...
- python中那些双下划线开头得函数和变量
Python中下划线---完全解读 Python 用下划线作为变量前缀和后缀指定特殊变量 _xxx 不能用’from module import *’导入 __xxx__ 系统定义名字 __x ...
- 【字符串算法1】 再谈字符串Hash(优雅的暴力)
[字符串算法1] 字符串Hash(优雅的暴力) [字符串算法2]Manacher算法 [字符串算法3]KMP算法 这里将讲述 [字符串算法1] 字符串Hash 老版原文: RK哈希(Rabin_Ka ...
- 字符串hash&&对字符串hash的理解
对字符串hash的一些总结: 1,首先,我们在转化的时候,取底的时候一般是取131这些数,因为要避免不同的字符串对应相同的hash值这种情况的出现.如果卡精度的时候,我们可以采取双模数的方式尽量减少 ...
- 字符串hash的学习部分 可以算是模板?
资料来自于http://www.bilibili.com/video/av7230433/ 定义这个字符串为s ①单hash hash[i] = (hash[i - 1] * p + idx(s[i] ...
随机推荐
- 在Ubuntu上安装openResty #1
在Ubuntu上安装openResty #1 OpenResty® 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方 ...
- 安装mysql后必须要做的一件事
Step 1. 检查默认账户和密码 $cat /etc/mysql/debian.cnf # 在ubuntu下查看默认账户名和密码 会看到 [client] host = localhost user ...
- ubuntu Tensorflow object detection API 开发环境搭建
https://blog.csdn.net/dy_guox/article/details/79111949 luo@luo-All-Series:~$ luo@luo-All-Series:~$ s ...
- Qt编写自定义控件29-颜色选取面板
一.前言 这个控件主要是模仿QColorDialog对话框中的颜色选取面板,提供一个十字形状的标识器,鼠标按下开始选取颜色,移动到哪就选择该处的颜色值,对应右侧颜色条放大显示,本控件的难点就是如何绘制 ...
- MobileNet V2深入理解
转载:https://zhuanlan.zhihu.com/p/33075914 MobileNet V2 论文初读 转载:https://blog.csdn.net/wfei101/article/ ...
- Spring事务管理4-----声明式事务管理(2)
声明式事务管理 基于AspectJ的 XML 方式配置 通过对事务管理器TransactionManager配置通知(增强),然后再配置切点和切面,详细见applicationContext.xml ...
- JAVA 基础编程练习题20 【程序 20 求前 20 项之和】
20 [程序 20 求前 20 项之和] 题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前 20 项之和. 程序分析:请抓住分子与分母的变化规律. pac ...
- 如何屏蔽掉烦人的www.google-analytics.com
有时候在开发的网站项目中会加载谷歌分析的js,并且加载的非常慢导致浏览器一直在转圈圈. 按下面的方法可屏蔽掉烦人的www.google-analytics.com 现在想只有屏蔽掉google-a ...
- Cognos Framework操作记录:开发复杂报表
设计一张数据库的表:TEST_001_ADDRESS 表结构: | 编号 | 姓名 | 省 | 市 | 县 | 公司 | 部门 | 职位 | | ---- | --- | -- | - | - | - ...
- jenkins:多个job时怎么按照一定顺序执行构建
一.安装Jenkins多项目构建插件(我已安装):Multijob 二.新建Multijob Project任务 三.配置