字符串哈希(算法题)
#include <bits/stdc++.h>
using namespace std;/* 使用unsigned long long类型存储哈希值,利用自然溢出实现自动取模 */
typedef unsigned long long ULL;
const int N = 100010; // 最大字符串长度
const int base = 133; // 哈希进制基数,选择质数减少碰撞概率
ULL p[N]; // 存储base的幂次 p[i] = base^i
ULL h[N]; // 前缀哈希数组 h[i]表示前i个字符的哈希值/* 计算子串[l,r]的哈希值(1-based下标) */
ULL get(int l, int r) {/* 公式推导:h[r] = h[l-1] * base^(r-l+1) + hash(s[l..r])因此子串哈希 = h[r] - h[l-1] * p[r-l+1] */return h[r] - h[l - 1] * p[r - l + 1];
}int main() {int n, m;cin >> n >> m; // 输入字符串长度n和查询次数mstring x;cin >> x; // 输入目标字符串/* 初始化哈希数组 */p[0] = 1; // base^0 = 1for (int i = 1; i <= n; i++) {/* 示例:当i=1时,h[1] = h[0]*base + s[0]的ASCII码值假设x = "abc",则:h[1] = 0 * 133 + ('a'-'a'+1) = 1h[2] = 1 * 133 + ('b'-'a'+1) = 133 + 2 = 135h[3] = 135 * 133 + 3 = 17955 + 3 = 17958 */h[i] = h[i - 1] * base + (x[i - 1] - 'a' + 1); // 字符串0-based转1-based/* 计算base的幂次:p[1] = base^1 = 133p[2] = base^2 = 133 * 133 = 17689 */p[i] = p[i - 1] * base;}/* 处理m个查询 */while (m--) {int l1, r1, l2, r2;cin >> l1 >> r1 >> l2 >> r2;/* 哈希比较过程示例:假设查询子串[1,2]和[3,4]1. 检查长度是否相同:r1-l1+1 == r2-l2+12. 计算哈希值:hash1 = h[2] - h[0] * p[2]hash2 = h[4] - h[2] * p[2]3. 若hash1 == hash2则认为相同(注意存在极小概率哈希碰撞) */if (get(l1, r1) == get(l2, r2)) {cout << "Yes" << endl;} else {cout << "No" << endl;}}return 0;
}
此篇参考了acwing算法基础课。