templates/hashed-deque.cpp
compilable
$cat templates/hashed-deque
Hashed Deque
Deque with O(1) rolling polynomial double hash for constant-time equality comparison.
#hashing#deque#rolling-hash#equality
Log in to track progress, save custom versions, and organize into collections.Log In
$cat source_code/
cpp
#include <bits/stdc++.h>
using namespace std;
using ll = long long;
struct HashedDeque {
static const int MAXN = 500005;
static const ll BASE = 1000000007;
static ll mod[2], pw[MAXN][2], inv[MAXN][2];
static bool inited;
deque<ll> dq;
ll val[2] = {};
int len = 0;
static ll power(ll b, ll e, ll m) {
ll r = 1; b %= m;
while (e > 0) { if (e & 1) r = r * b % m; b = b * b % m; e >>= 1; }
return r;
}
static void init() {
if (inited) return; inited = true;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
auto nextPrime = [](ll x) { while (true) { bool ok = x > 1; for (ll i = 2; i * i <= x && ok; i++) ok = x % i != 0; if (ok) return x; x++; } };
mod[0] = nextPrime(900000000LL + rng() % 100000000);
mod[1] = nextPrime(900000000LL + rng() % 100000000);
while (mod[1] == mod[0]) mod[1] = nextPrime(900000000LL + rng() % 100000000);
for (int j = 0; j < 2; j++) {
pw[0][j] = inv[0][j] = 1;
ll invB = power(BASE, mod[j] - 2, mod[j]);
for (int i = 1; i < MAXN; i++) {
pw[i][j] = pw[i-1][j] * BASE % mod[j];
inv[i][j] = inv[i-1][j] * invB % mod[j];
}
}
}
HashedDeque() { init(); }
void pushBack(ll x) {
for (int j = 0; j < 2; j++)
val[j] = (val[j] * BASE + x) % mod[j];
dq.push_back(x); len++;
}
void pushFront(ll x) {
for (int j = 0; j < 2; j++)
val[j] = (x * pw[len][j] + val[j]) % mod[j];
dq.push_front(x); len++;
}
void popBack() {
ll x = dq.back(); dq.pop_back(); len--;
for (int j = 0; j < 2; j++)
val[j] = (val[j] - x % mod[j] + mod[j]) % mod[j] * inv[1][j] % mod[j];
}
void popFront() {
ll x = dq.front(); dq.pop_front(); len--;
for (int j = 0; j < 2; j++)
val[j] = (val[j] - x * pw[len][j] % mod[j] + mod[j]) % mod[j];
}
int size() const { return len; }
bool operator==(const HashedDeque &o) const { return len == o.len && val[0] == o.val[0] && val[1] == o.val[1]; }
};
ll HashedDeque::mod[2];
ll HashedDeque::pw[HashedDeque::MAXN][2];
ll HashedDeque::inv[HashedDeque::MAXN][2];
bool HashedDeque::inited = false;71 linesutf-8
$cat explanation_notes.md
notes_viewer --renderedmarkdown (math enabled)
Hashed Deque
A double-ended queue that maintains a rolling polynomial hash, enabling equality comparison between two deques.
Hash Updates
For sequence with hash :
All operations using precomputed powers and modular inverses.
When to Use
Anti-Hack
Two random prime moduli selected at runtime. Double hashing reduces collision probability.