字符串哈希
字符串哈希
哈希基本思想就是两个对象的映射,字符串哈希则是将一个字符串映射到一个数上,用这个数即可代表这个字符串,而这个数被称为哈希值
那么如何计算哈希值呢?
我们知道字符串的每个字符其实相等于一个数字,因此我们可以把每个字符串看成一个整数,之后将其转化为P进制下mod一个质数的数字,而这个数也就是这个字符串的哈希值。
例:"ABCD" ----->
一般我们取P为131 或 13331, Q 为 可以保证大部分情况下不出现哈希冲突
而mod Q 的操作我们可以通过将变量定义为unsigned long long来省略,因为在ull下当数值溢出范围后会自动对取模
哈希前缀
我们定义h[i] 表示字符串第1个到第i个字符组成的子串的哈希值
那如何求l到r的子串哈希值呢?
结论:res = h[r] - h[l - 1] * p[r - l + 1]
**我们不能直接向前缀和那样h[r] - h[l - 1], 因为此时在h[r]中1 - l-1的哈希值与h[l - 1]并不相同,而差的值正好就是他们直接相差的位数,因此乘上即可,这里我们已经预处理p[i]来表示了 **
通过这样的方法在预处理后我们可以用的复杂度获得一段字符的哈希值,并利用哈希值高效完成一系列其他操作
代码示例:
//#pragma comment(linker, "/STACK:10240000000000,10240000000000")
//#pragma GCC optimize(2)
#include <bits/stdc++.h>
using namespace std;
#define rep(i,a,b) for (int i=(a);i<=(b);++i)
#define per(i,b,a) for (int i=(b);i>=(a);--i)
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define itt iterator
#define endl '\n'
#define IOS ios::sync_with_stdio(0); cin.tie(0);
#define lowbit(x) x & (-x)
#define clr(x) memset(x, 0, sizeof(x));
#define fi first
#define se second
#define mp make_pair
#define MOD 1000000007
typedef vector<int> vii;
typedef vector<long long> vll;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef set<int> si;
typedef set<ll> sll;
ll ksm(ll a, ll b, ll p) {if (b == 0) return 1; ll ns = ksm(a, b >> 1, p); ns = ns * ns % p; if (b & 1) ns = ns * a % p; return ns;}
const int MAXN = 0x7fffffff;
const int N = 1e5 + 5, P = 131;
ull p[N];
ull h[N];
int n, m;
char str[N];
ull get(int l, int r)
{
return h[r] - h[l - 1] * p[r - l + 1];
}
int main ()
{
//IOS;
cin >> n >> m;
cin >> str + 1;
p[0] = 1;
for(int i = 1; i <= n; i ++)
{
p[i] = p[i - 1] * P; //预处理p数组
h[i] = h[i - 1] * P + str[i];//预处理哈希前缀数组
}
while(m --)
{
int l1, r1, l2, r2;
cin >> l1 >> r1 >> l2 >> r2;
if(get(l1, r1) == get(l2, r2)) puts("Yes");
else puts("No");
}
return 0;
}
/*
*/
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?