-
Notifications
You must be signed in to change notification settings - Fork 0
/
Hashing.java
96 lines (72 loc) · 1.97 KB
/
Hashing.java
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
class StringHashing{
private long P = 31;
private long M = (long)1e9+7;
final int N = (int)1e6;
long []fxp;
long []prefixHash;
long []modInv;
long fastExponentiation(long a, long b){
long res = 1;
while(b>0){
if((b&1) > 0){
res = (res * a)%M;
}
b>>=1;
a = (a*a)%M;
}
return res;
}
StringHashing(){
fxp = new long [(int) N];
fxp[0] = 1;
for(int i = 1; i<N; i++){
/*
fxp[i] = P^i % M
fxp[i-1] = P^(i-1) % M;
fxp[i] = (P^(i-1) * P)%M = (P^(i-1) % M * P%M) % M (Using (a*b)%m)
fxp[i] = (fxp[i-1] * P) % M;
*/
fxp[i] = (fxp[i-1] * P) % M;
}
modInv = new long[N];
/*
modInv(a) modulo M, a^(M-2)%M
*/
for(int i=0; i<N; i++){
modInv[i] = fastExponentiation(fxp[i], M-2);
}
}
long getHash(String s){
/*
Hashvalue of string s
(s[0] * P^0 + s[1] * P^1 + s[2] * P^2 + s[3] * P^3 +...+s[n-1] * P^(n-1))%M
*/
long hashval = 0;
for(int i=0;i<s.length();i++){
long ascii = (s.charAt(i) - 'a') + 1L;
hashval = (hashval + (ascii * fxp[i])%M) % M;
}
return hashval;
}
public void precompute(String s){
prefixHash = new long [s.length()];
long hashval = 0;
for(int i=0;i<s.length();i++){
long ascii = (s.charAt(i) - 'a') + 1L;
hashval = (hashval + (ascii * fxp[i])%M) % M;
prefixHash[i] = hashval;
}
}
public long getSubstringHash(int l, int r){
//(a-b)%m = (a%m - b%m + m)%m
long val = (prefixHash[r] - (l > 0 ? prefixHash[l-1] : 0) + M)%M;
val = (val * modInv[l])%M;
return val;
}
}
/*
M = 35
hashval = 33
x = 32
hashval += 32 ===> 33+32 = 65
*/