-
Notifications
You must be signed in to change notification settings - Fork 153
/
string_hashing.cpp
70 lines (60 loc) · 1.74 KB
/
string_hashing.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
/**
* Description: String Hashing
* Usage: initalize O(N), getHash O(n), getSubHash O(1), getRevSubHash O(1)
* Note: In case double hashing is required http://codeforces.com/contest/710/submission/20094958
* Source: https://github.com/dragonslayerx
*/
long long power(long long n, long long m, long long MOD){
if (m == 0) return 1;
long long x = power(n, m/2, MOD);
if (!(m & 1)) return (x * x) % MOD;
else return (((x * x) % MOD) * n) % MOD;
}
class StringHash {
const static int MAX = 300005;
ll b = 100000009;
ll m = 1000000007;
ll B[MAX], inverseB[MAX];
void initialize() {
B[0]=1;
for (int i = 1; i < MAX; i++) {
B[i]=(B[i-1]*b)%m;
}
inverseB[MAX-1]=power(B[MAX-1], m-2, m);
for (int i = MAX-2; i >= 0; i--) {
inverseB[i]=(inverseB[i+1]*b)%m;
}
}
public:
StringHash() {
initialize();
}
ll getHash(char *s) {
long long h = 0;
for (int i = 0; s[i]; i++) {
h = (h + (s[i] * B[i])) % m;
}
return h;
}
int length=0;
ll h[MAX], revh[MAX];
ll construct(char *s) {
length = strlen(s);
h[0]=0, revh[length+1]=0;
for (int i = 0, j = 1; s[i]; i++, j++) {
h[j] = (h[j-1] + (s[i] * B[i]) % m) % m ;
}
for (int i = length-1, j = length, k = 0; i >= 0; i--, j--, k++) {
revh[j] = (revh[j+1] + ((s[i] * B[k]) % m)) % m;
}
return h[length];
}
ll getSubHash(int i, int j) {
i++, j++;
return ((h[j] + (m-h[i-1])) * inverseB[i-1]) % m;
}
ll getRevHash(int i, int j) {
i++, j++;
return ((revh[i] + (m-revh[j+1])) * inverseB[length-j]) % m;
}
};