ACM入门之哈希

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ACM入门之哈希相关的知识,希望对你有一定的参考价值。

哈希在竞赛中也是一个很常用,且非常厉害的一个算法。

哈希的主要思想就是把一个东西转换成一个大整数,这样比较两个东西是否相等的就只要比较两个整数是否相等就行了,
比较的时间复杂度是O(1)的。

举一个比较常见的例子:比较俩字符串是否相等,我们可以将字符串变成一个值,然后直接比较这俩字符串的哈希值就行了。
可能你会有疑问?在c++中string 不是可以直接就比较了么? 为啥还要用哈希呢?
假如人家问的是俩矩阵是否相等呢?假如人家问这个矩阵是否在一个大矩阵中出现过呢?
那么如何存矩阵呢?我们就可以用二维哈希,将矩阵也映射成一个哈希值,这样比较矩阵直接比较哈希值就行了。

其实,通过上面你已经对哈希有了一个初步的了解了。哈希它其实就是将一些特别难存的东西,通过某种手法变成一个唯一的值,
然后只需比较哈希值就行了。

哈希常见的几种模型:

  • 一维哈希(字符串)
  • 二维矩阵哈希

核心思想:将字符串看成P进制数,P的经验值是131,13331,233,2333,10007等质数 取这些值的冲突概率低
取模的时候选一个较大的质数避免冲突。
小技巧:取模的数用2^64,这样直接用unsigned long long存储,溢出的结果就是取模的结果

一维哈希模板:

typedef long long int LL;
const int M=233;//是我们自己选择的进制数,一般可以选233,2333,10007等质数
const int mod=1e9+7;//一般选一个比较大的质数
LL get(string s)//获取字符串对应的哈希值

	LL sum=0;
	for(int i=0;i<s.size();i++) sum=(sum*M+s[i]-'a')%mod;
	return sum;

typedef unsigned long long int ull;
const int N=1e5+10;
const int M=233;
ull h[N],base[N];
ull query(int l,int r)//获取字符串[l,r]的哈希值

    return h[r]-h[l-1]*base[r-l+1];

void init(string s)//初始化哈希

    int n=s.size();
    s="0"+s;//让其下标从1开始
    base[0]=1;
    for(int i=1;i<=n;i++)
    
        h[i]=h[i-1]*M+s[i];
        base[i]=base[i-1]*M;// base[i]=M^i
    

ull merge(int l1, int r1, int l2, int r2)
//求[l1,r1],[l2,r2]子串并的哈希值

    return query(l1, r1) * base[r2 - l2 + 1] + query(l2, r2);

字符串哈希入门:
P3370 【模板】字符串哈希
841. 字符串哈希
103. 子串查找

二维哈希模板

typedef long long int ll;
const int N=1010;
ll h[N][N],base1[N],base2[N];
int a[N][N],n,m;
void init()//构建

    base1[0]=base2[0]=1;
    for(int i=1;i<N;i++)
    
        base1[i]=base1[i-1]*131;
        base2[i]=base2[i-1]*233;
    
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            h[i][j]=h[i][j-1]*131+a[i][j];//行哈希
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            h[i][j]=h[i-1][j]*233+h[i][j];//列哈希

ll query(int x1,int y1,int x2,int y2)//查询矩阵的哈希值

    return h[x2][y2]-h[x2][y1-1]*base1[y2-y1+1]-h[x1-1][y2]*base2[x2-x1+1]
    +h[x1-1][y1-1]*base1[y2-y1+1]*base2[x2-x1 + 1];

二维哈希习题:
Matrix
矩阵

好的文章推荐:
哈希入门
哈希基础例题
二维哈希

以上是关于ACM入门之哈希的主要内容,如果未能解决你的问题,请参考以下文章

重构·改善既有代码的设计.04之重构手法(下)完结

ACM入门之搜索

ACM入门之二分

ACM入门之差分

ACM入门之欧拉序列

ACM入门之欧拉序列