diff --git a/algorithms/strings/hash-range-query.cpp b/algorithms/strings/hash-range-query.cpp index a239dd63..726bc60d 100644 --- a/algorithms/strings/hash-range-query.cpp +++ b/algorithms/strings/hash-range-query.cpp @@ -1,28 +1,36 @@ +const ll P = 31; +const ll MOD = 1e9 + 9; +const int MAXN(1e6); + +ll ppow[MAXN+1]; +void pre_calc() { + ppow[0] = 1; + for (int i = 1; i <= MAXN; i++) + ppow[i] = (ppow[i-1] * P) % MOD; +} + struct Hash { - const ll P = 31; - const ll mod = 1e9 + 7; - string s; int n; - vll h, hi, p; - Hash() {} - Hash(string s) : s(s), n(s.size()), h(n), hi(n), p(n) { - for (int i = 0; i < n; i++) - p[i] = (i ? P * p[i - 1] : 1) % mod; - for (int i = 0; i < n; i++) - h[i] = (s[i] + (i ? h[i - 1] : 0) * P) % mod; - for (int i = n - 1; i >= 0; i--) - hi[i] = - (s[i] + (i + 1 < n ? hi[i + 1] : 0) * P) % mod; + vll h, hi; + Hash(const string &s) : n(s.size()), h(n), hi(n) { + h[0] = s[0]; + hi[n-1] = s[n-1]; + for (int i = 1; i < n ; i++) { + h[i] = (s[i] + h[i - 1] * P) % MOD; + hi[n-i-1] = (s[n-i-1] + hi[n - i - 1] * P) % MOD; + } } - ll query(int l, int r) { + + ll qry(int l, int r) { ll hash = - (h[r] - (l ? h[l - 1] * p[r - l + 1] % mod : 0)); - return hash < 0 ? hash + mod : hash; + (h[r] - (l ? h[l - 1] * ppow[r - l + 1] % MOD : 0)); + return hash < 0 ? hash + MOD : hash; } - ll query_inv(int l, int r) { + + ll qry_inv(int l, int r) { ll hash = (hi[l] - - (r + 1 < n ? hi[r + 1] * p[r - l + 1] % mod : 0)); - return hash < 0 ? hash + mod : hash; + (r + 1 < n ? hi[r + 1] * ppow[r - l + 1] % MOD : 0)); + return hash < 0 ? hash + MOD : hash; } };