【刷题】数据结构——字符串Hash【模板】

假设有字符串:ABCABCD
预处理前缀的哈希值
h[0] = ""的哈希值
h[1] = "A"的哈希值
h[2] = "AB"的哈希值
h[3] = "ABC"的哈希值
h[4] = "ABCA"的哈希值


哈希值计算方法,转化成P进制。
以26个大写字母为例,假设转化成26进制,那么"ABCA"的哈希值就是 ( 1 ∗ 2 6 3 + 2 ∗ 2 6 2 + 3 ∗ 2 6 1 + 1 ∗ 2 6 0 ) m o d Q (1*26^3+2*26^2+3*26^1+1*26^0) mod Q (1263+2262+3261+1260)modQ

注意不能映射成0,例如A是0,那么A…A也是0,无法区分。

P=131或13331,Q=2^64时,字符串哈希基本不会冲突。
可以用unsigned long long存储,这样相当于自动模Q

这里不考虑冲突时的情况。


有了预处理的哈希值,可以得到字符串任意子段的哈希值,不妨设子段是[L, R]
在这里插入图片描述
则子段的哈希值是 h [ R ] − h [ L − 1 ] ∗ P R − L + 1 h[R] - h[L-1]*P^{R-L+1} h[R]h[L1]PRL+1
其中 h [ L − 1 ] ∗ P R − L + 1 h[L-1]*P^{R-L+1} h[L1]PRL+1是为了使 h [ L − 1 ] h[L-1] h[L1]对齐 h [ R ] h[R] h[R]的前面L-1位。

在这里插入图片描述

#include <iostream>
using namespace std;

typedef unsigned long long ULL;

const int N = 100005, P = 131;
ULL h[N], p[N];

int n, m;
char str[N];

int main() {
    scanf("%d%d%s", &n, &m, str);
    p[0] = 1;
    for (int i = 1; i <= n; i ++ ) {
        p[i] = p[i - 1] * P;
        h[i] = h[i - 1] * P + str[i - 1];
    }
    int l1, r1, l2, r2;
    while (m -- ) {
        scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
        ULL t1 = h[r1] - h[l1 - 1] * p[r1 - l1 + 1];
        ULL t2 = h[r2] - h[l2 - 1] * p[r2 - l2 + 1];
        if (t1 == t2) printf("Yes\n");
        else printf("No\n");
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值