From bb0883c57c875589181b3d9578cbea9c3d4107fd Mon Sep 17 00:00:00 2001 From: subcrip Date: Sat, 7 Dec 2024 16:54:34 +0000 Subject: [PATCH] Update string/hash_vec.cc Signed-off-by: subcrip --- string/hash_vec.cc | 53 +++++++++++++++++++++++----------------------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/string/hash_vec.cc b/string/hash_vec.cc index 836e6d6..85a8a41 100644 --- a/string/hash_vec.cc +++ b/string/hash_vec.cc @@ -1,49 +1,51 @@ -static vector> power1; -static vector> power2; -static const ll b = rd(); +static vector power1; +static vector power2; +static const ll b = rd() % INF; +static const ll b1 = inverse(b, MDL1); +static const ll b2 = inverse(b, MDL2); template struct hash_vec { using hash_type = pll; - MLL hash1; - MLL hash2; + ll hash1; + ll hash2; vector<_Tp> seq; size_t size() { return seq.size(); } void push_back(const _Tp& x) { - hash1 = hash1 * b + x; - hash2 = hash2 * b + x; + hash1 = (hash1 * b % MDL1 + x) % MDL1; + hash2 = (hash2 * b % MDL2 + x) % MDL2; seq.push_back(x); } void push_front(const _Tp& x) { size_t length = size(); - hash1 += x * power1[length]; - hash2 += x * power2[length]; + hash1 = (hash1 + x * power1[length] % MDL1) % MDL1; + hash2 = (hash2 + x * power2[length] % MDL2) % MDL2; seq.push_front(x); } void pop_back() { _Tp e = seq.back(); seq.pop_back(); - hash1 = (hash1 - e) / b; - hash2 = (hash2 - e) / b; + hash1 = mod(hash1 - e, MDL1) * b1 % MDL1; + hash2 = mod(hash2 - e, MDL2) * b2 % MDL2; } void pop_front() { _Tp e = seq.front(); seq.pop_front(); int length = seq.size(); - hash1 -= e * power1[length]; - hash2 -= e * power2[length]; + hash1 = mod(hash1 - e * power1[length] % MDL1, MDL1); + hash2 = mod(hash2 - e * power2[length] % MDL2, MDL2); } void set(size_t pos, const _Tp& value) { int length = seq.size(); int old_value = seq[pos]; - hash1 += (value - old_value) * power1[length - 1 - pos]; - hash2 += (value - old_value) * power2[length - 1 - pos]; + hash1 = (hash1 + (value - old_value) * power1[length - 1 - pos] % MDL1) % MDL1; + hash2 = (hash2 + (value - old_value) * power2[length - 2 - pos] % MDL2) % MDL2; seq[pos] = value; } const _Tp& operator[](size_t pos) { return seq[pos]; } hash_type hash() { - return {hash1.val, hash2.val}; + return { hash1, hash2 }; } void clear() { hash1 = 0; @@ -52,13 +54,13 @@ struct hash_vec { } hash_vec(size_t maxn) { clear(); - MLL c1 = power1.size() ? power1.back() * b : 1; - MLL c2 = power2.size() ? power2.back() * b : 1; + ll c1 = power1.size() ? power1.back() * b % MDL1 : 1; + ll c2 = power2.size() ? power2.back() * b % MDL2 : 1; for (int i = power1.size(); i < maxn; ++i) { power1.push_back(c1); power2.push_back(c2); - c1 *= b; - c2 *= b; + c1 = c1 * b % MDL1; + c2 = c2 * b % MDL2; } } hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) { @@ -67,9 +69,8 @@ struct hash_vec { } } }; - struct range_hash { - vector, MLL>> hp; + vector hp; template range_hash(const T& vec) { hp.emplace_back(); @@ -79,13 +80,11 @@ struct range_hash { hp.emplace_back(hs.hash()); } } - /// query hash of subarray [l, r]. Index starts from 0. - pair, MLL> range_query(size_t l, size_t r) { + inline pll range_query(size_t l, size_t r) { return { - (hp[r + 1].first - hp[l].first * power1[r + 1 - l]), - (hp[r + 1].second - hp[l].second * power2[r + 1 - l]), + mod(hp[r + 1].first - hp[l].first * power1[r + 1 - l] % MDL1, MDL1), + mod(hp[r + 1].second - hp[l].second * power2[r + 1 - l] % MDL2, MDL2), }; } }; -