|
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