|
1 | 1 | #pragma once |
2 | | -//! https://codeforces.com/blog/entry/4898#comment-157965 |
| 2 | +//! https://codeforces.com/blog/entry/4898 |
| 3 | +//! https://codeforces.com/blog/entry/60442 |
| 4 | +//! https://codeforces.com/blog/entry/129538 |
| 5 | +//! p = probability of collision ~= 1/((1e9+7)*(1e9+9)) |
| 6 | +//! probability of collision over q comparisons ~= |
| 7 | +//! (1 - (1/p))^q ~= 1 - (1/p)^q |
| 8 | +//! checking if n hashes are pairwise distinct is the same |
| 9 | +//! as doing q = (n choose 2) ~= n^2 comparisons |
3 | 10 | //! - use random base to avoid getting hacked on codeforces |
4 | | -//! - work mod 1e9+7 if birthday paradox is not a problem |
5 | 11 | //! @time O(n + q) |
6 | 12 | //! @space O(n) |
7 | | -using mint = array<ll, 2>; |
8 | | -constexpr mint mod = {ll(1e9 + 7), ll(1e9 + 9)}; |
| 13 | +using hsh = array<ll, 2>; |
| 14 | +constexpr hsh mod = {ll(1e9 + 7), ll(1e9 + 9)}; |
9 | 15 | const ll base = 239017; |
10 | 16 | struct str_hash { |
11 | | - vector<mint> ha, pw; |
| 17 | + vector<hsh> ha, pw; |
12 | 18 | str_hash(const auto& s): ha(sz(s) + 1), pw(ha) { |
13 | 19 | pw[0] = {1, 1}; |
14 | 20 | rep(i, 0, sz(s)) rep(j, 0, 2) { |
15 | 21 | pw[i + 1][j] = pw[i][j] * base % mod[j]; |
16 | 22 | ha[i + 1][j] = (ha[i][j] * base + s[i] + 1) % mod[j]; |
17 | 23 | } |
18 | 24 | } |
19 | | - mint subarray(int l, int r) { // [l, r) |
20 | | - mint res; |
| 25 | + hsh subarray(int l, int r) { // [l, r) |
| 26 | + hsh res; |
21 | 27 | rep(j, 0, 2) { |
22 | 28 | res[j] = ha[r][j] - ha[l][j] * pw[r - l][j] % mod[j]; |
23 | 29 | if (res[j] < 0) res[j] += mod[j]; |
|
0 commit comments