1
0
Fork 0

Update string/hash_vec.cc

Signed-off-by: subcrip <contact@subc.rip>
This commit is contained in:
subcrip 2024-12-07 16:54:34 +00:00
parent 774d9e829b
commit bb0883c57c
1 changed files with 26 additions and 27 deletions

View File

@ -1,49 +1,51 @@
static vector<MLL<MDL1>> power1; static vector<ll> power1;
static vector<MLL<MDL2>> power2; static vector<ll> power2;
static const ll b = rd(); static const ll b = rd() % INF;
static const ll b1 = inverse(b, MDL1);
static const ll b2 = inverse(b, MDL2);
template <typename _Tp> template <typename _Tp>
struct hash_vec { struct hash_vec {
using hash_type = pll; using hash_type = pll;
MLL<MDL1> hash1; ll hash1;
MLL<MDL2> hash2; ll hash2;
vector<_Tp> seq; vector<_Tp> seq;
size_t size() { size_t size() {
return seq.size(); return seq.size();
} }
void push_back(const _Tp& x) { void push_back(const _Tp& x) {
hash1 = hash1 * b + x; hash1 = (hash1 * b % MDL1 + x) % MDL1;
hash2 = hash2 * b + x; hash2 = (hash2 * b % MDL2 + x) % MDL2;
seq.push_back(x); seq.push_back(x);
} }
void push_front(const _Tp& x) { void push_front(const _Tp& x) {
size_t length = size(); size_t length = size();
hash1 += x * power1[length]; hash1 = (hash1 + x * power1[length] % MDL1) % MDL1;
hash2 += x * power2[length]; hash2 = (hash2 + x * power2[length] % MDL2) % MDL2;
seq.push_front(x); seq.push_front(x);
} }
void pop_back() { void pop_back() {
_Tp e = seq.back(); seq.pop_back(); _Tp e = seq.back(); seq.pop_back();
hash1 = (hash1 - e) / b; hash1 = mod(hash1 - e, MDL1) * b1 % MDL1;
hash2 = (hash2 - e) / b; hash2 = mod(hash2 - e, MDL2) * b2 % MDL2;
} }
void pop_front() { void pop_front() {
_Tp e = seq.front(); seq.pop_front(); _Tp e = seq.front(); seq.pop_front();
int length = seq.size(); int length = seq.size();
hash1 -= e * power1[length]; hash1 = mod(hash1 - e * power1[length] % MDL1, MDL1);
hash2 -= e * power2[length]; hash2 = mod(hash2 - e * power2[length] % MDL2, MDL2);
} }
void set(size_t pos, const _Tp& value) { void set(size_t pos, const _Tp& value) {
int length = seq.size(); int length = seq.size();
int old_value = seq[pos]; int old_value = seq[pos];
hash1 += (value - old_value) * power1[length - 1 - pos]; hash1 = (hash1 + (value - old_value) * power1[length - 1 - pos] % MDL1) % MDL1;
hash2 += (value - old_value) * power2[length - 1 - pos]; hash2 = (hash2 + (value - old_value) * power2[length - 2 - pos] % MDL2) % MDL2;
seq[pos] = value; seq[pos] = value;
} }
const _Tp& operator[](size_t pos) { const _Tp& operator[](size_t pos) {
return seq[pos]; return seq[pos];
} }
hash_type hash() { hash_type hash() {
return {hash1.val, hash2.val}; return { hash1, hash2 };
} }
void clear() { void clear() {
hash1 = 0; hash1 = 0;
@ -52,13 +54,13 @@ struct hash_vec {
} }
hash_vec(size_t maxn) { hash_vec(size_t maxn) {
clear(); clear();
MLL<MDL1> c1 = power1.size() ? power1.back() * b : 1; ll c1 = power1.size() ? power1.back() * b % MDL1 : 1;
MLL<MDL2> c2 = power2.size() ? power2.back() * b : 1; ll c2 = power2.size() ? power2.back() * b % MDL2 : 1;
for (int i = power1.size(); i < maxn; ++i) { for (int i = power1.size(); i < maxn; ++i) {
power1.push_back(c1); power1.push_back(c1);
power2.push_back(c2); power2.push_back(c2);
c1 *= b; c1 = c1 * b % MDL1;
c2 *= b; c2 = c2 * b % MDL2;
} }
} }
hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) { hash_vec(size_t maxn, const _Tp& init_value) : hash_vec(maxn) {
@ -67,9 +69,8 @@ struct hash_vec {
} }
} }
}; };
struct range_hash { struct range_hash {
vector<pair<MLL<MDL1>, MLL<MDL2>>> hp; vector<pll> hp;
template <typename T> template <typename T>
range_hash(const T& vec) { range_hash(const T& vec) {
hp.emplace_back(); hp.emplace_back();
@ -79,13 +80,11 @@ struct range_hash {
hp.emplace_back(hs.hash()); hp.emplace_back(hs.hash());
} }
} }
/// query hash of subarray [l, r]. Index starts from 0. /// query hash of subarray [l, r]. Index starts from 0.
pair<MLL<MDL1>, MLL<MDL2>> range_query(size_t l, size_t r) { inline pll range_query(size_t l, size_t r) {
return { return {
(hp[r + 1].first - hp[l].first * power1[r + 1 - l]), mod(hp[r + 1].first - hp[l].first * power1[r + 1 - l] % MDL1, MDL1),
(hp[r + 1].second - hp[l].second * power2[r + 1 - l]), mod(hp[r + 1].second - hp[l].second * power2[r + 1 - l] % MDL2, MDL2),
}; };
} }
}; };