这里不讲解法,只给模板。需要自取,顺便留赞 + 转发。
#include <iostream>
#include <cstdio>
#include <vector>
using namespace std;
struct hash_string {
string S; int mod, p;
vector<long long> h;
vector<long long> p_pow;
hash_string() {}
hash_string(int mod, int p):mod(mod), p(p) { p_pow.emplace_back(1ll); h.emplace_back(0ll); }
hash_string(string S, int mod, int p) : S(S), mod(mod), p(p) { // 初始化字符串和模数
p_pow.emplace_back(1ll); h.emplace_back(0ll);
for (auto c : S) {
h.emplace_back((h.back() * p + c) % mod);
p_pow.emplace_back(p_pow.back() * p % mod);
}
}
void insert(char c) { // 插入字符
S += c; h.emplace_back((h.back() * p + c) % mod);
p_pow.emplace_back(p_pow.back() * p % mod);
}
int hash_value(int l, int r) { // 查询哈希值
return ((h[r] - h[l - 1] * p_pow[r - l + 1] % mod) % mod + mod) % mod;
}
};
struct double_hash {
string S; hash_string hash1, hash2;
double_hash() {}
double_hash(string S) : S(S) { // 初始化。传入字符串,哈希模数为原定。
hash1 = hash_string(S, (int)1e9 + 7, 1331);
hash2 = hash_string(S, (int)1e9 + 9, 1331);
}
double_hash(string S, int mod1, int p1, int mod2, int p2) : S(S) { // 初始化,传入字符串和哈希模数
hash1 = hash_string(S, mod1, p1);
hash2 = hash_string(S, mod2, p2);
}
bool equal(int l1, int r1, int l2, int r2) { // 判断两段串是否相等。
return (hash1.hash_value(l1, r1) == hash1.hash_value(l2, r2) and
hash2.hash_value(l1, r1) == hash2.hash_value(l2, r2));
}
void insert(char c) { // 插入字符
hash1.insert(c), hash2.insert(c);
}
};
int main() {
int n, m; string s;
scanf("%d%d", &n, &m);
cin >> s;
hash_string hash1(s, 13331, 131); // 初始化单哈希。
hash_string hash2(13331, 131); // 这种初始化方法和 hash1 相同。
for (auto c : s) hash2.insert(c);
double_hash hash3(s); // 初始化双哈希。模数是系统自定的。
double_hash hash4(s, 13331, 131, 13331, 13); // 初始化双哈希,模数可以自设。
while (m -- ) {
int l1, r1, l2, r2;
scanf("%d%d%d%d", &l1, &r1, &l2, &r2);
puts(hash.equal(l1, r1, l2, r2) ? "Yes" : "No");
}
return 0;
}