前言

字符串$Hash$是将复杂的信息映射到一个简单的值域内,并使每一个字符串尽量均匀分布在其中,几乎不产生冲突(尽量让两个不同值不被映射成相同的值)的一种方法。

因为$Hash$更注重对其方法的理解,所以笔者就简单讲一下其思路,不会太过详细的讲解。

$Hash$的基本过程

我们采用进制的思想,把该字符串转化为某进制下的一个数并存储起来,之后就可以$O(1)$查询和匹配该字符串及其子串。

我们先来看模板题:

题意简述:给定$N$个字符串,求有多少个不同的字符串。

思路:都说是$Hash$的板子了,当然要用$Hash$了。我们可以用$Hash$将字符串映射为$base$进制的数,记录每一个字符串的值,再判断有多少个不同的值即可。

#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstring>
#include <algorithm>
#define il inline
#define ll long long
#define int long long
#define ull unsigned long long
#define re register
#define gc getchar
using namespace std;
//------------------------初始程序-------------------------- 
il int read(){
	re int x=0;re bool f=0;re char ch=gc();
	while(!isdigit(ch)){f|=ch=='-';ch=gc();}
	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
	return f?-x:x;
}

il int max(int a,int b){
	return a>b?a:b;
}

il int min(int a,int b){
	return a<b?a:b;
}


//------------------------初始程序-------------------------- 

const int N=1e4+10,MOD=1e9+7;
ull base=131,a[N];//用unsigned long long 让它自然溢出
//a[i]记录第i个字符串的Hash值
char opt[N];//记录输入的字符串
int n,ans=1;//ans从1开始是因为第一个数一定跟其他数是不相同的

il ull hashe(int len) {
	ull res=0;//记录base进制下该字符串的值
	for(re int i=1;i<=len;++i) {
		res=(res*base+opt[i]+1)%MOD;
      	//生成该值,相当于把之前的值左移一位再加上该字符串第i位所代表的值  
      	//这里一定要注意加1,防止当前位值为0,降低与其他值冲突的可能 
	}
	return res;
}


signed main()
{
	n=read();
	for(re int i=1;i<=n;++i) {
		scanf("%s",opt+1);
		int len=strlen(opt+1);
		a[i]=hashe(len);
	}	
	sort(a+1,a+n+1);//把该值从小到大排序
	for(re int i=1;i<n;++i) 
		if(a[i]!=a[i+1]) ++ans;//如果相邻两个数不相等,答案加一
	printf("%lld\n",ans);
	return 0;
}

P3370 【模板】字符串哈希(Hash+Trie树的题解)(我的Hash代码)

P2957 [USACO09OCT]Barn Echoes G(求前缀后缀最长相等长度)(Hash题解)(我的Hash代码)

P7469 [NOI Online 2021 提高组] 积木小赛(民间数据)(题解)(我的代码)

本题有一堆正解,但$Hash$可能是其中最好想的(奈何考场没想到),像之前所说,我们可以用$Hash$来求$t$的任意子串,然后用一个二维数组(设为$pos[i][j]$)记录第$i$位之后的第一个出现$j$字符的下标,$O(n^2)$暴力枚举$t$的每一个子串,将子串的$Hash$值记录,最后去重即可。

P5043 【模板】树同构([BJOI2015]树的同构)(题解)(我的代码)

本题要求我们将$Hash$运用到树上,对于树上的每一个节点,我们都可以求出以该节点为根节点的整棵树的$Hash$值,再在之前求出的$Hash$值中找到相同的输出即可。

以下为树同构另一道经典题(博主可能没时间做了,先咕着):

P4323 [JSOI2016]独特的树叶