bhupixb

Hash for a string

Feb 8th, 2020
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.25 KB | None | 0 0
  1. // I can't tell you what it really is,
  2. // I can only tell you what it feels like.
  3. #include "bits/stdc++.h"
  4. using namespace std;
  5.  
  6. const int MOD = (1L<<31)-1;
  7.  
  8.  
  9. int rand(int l, int r){
  10. static std::mt19937 rng(std::chrono::steady_clock::now().time_since_epoch().count());
  11. std::uniform_int_distribution<int> ludo(l, r); return ludo(rng);
  12. }
  13.  
  14. struct mod_int {
  15. int val;
  16. mod_int(long long v = 0) {
  17. if (v < 0) v = v % MOD + MOD;
  18. if (v >= MOD) v %= MOD;
  19. val = v;
  20. }
  21.  
  22. static int mod_inv(int a, int m = MOD) {
  23. int g = m, r = a, x = 0, y = 1;
  24. while (r != 0) {
  25. int q = g / r;
  26. g %= r; swap(g, r);
  27. x -= q * y; swap(x, y);
  28. }
  29. return x < 0 ? x + m : x;
  30. }
  31.  
  32. mod_int& operator+=(const mod_int &other) {
  33. val += other.val;
  34. if (val >= MOD) val -= MOD;
  35. return *this;
  36. }
  37.  
  38. mod_int& operator-=(const mod_int &other) {
  39. val -= other.val;
  40. if (val < 0) val += MOD;
  41. return *this;
  42. }
  43.  
  44. static unsigned fast_mod(uint64_t x, unsigned m = MOD) {
  45. return x % m;
  46. }
  47.  
  48. mod_int& operator*=(const mod_int &other) {
  49. val = fast_mod((uint64_t) val * other.val);
  50. return *this;
  51. }
  52.  
  53. mod_int& operator/=(const mod_int &other) {
  54. return *this *= other.inv();
  55. }
  56.  
  57. friend mod_int operator+(const mod_int &a, const mod_int &b) { return mod_int(a) += b; }
  58. friend mod_int operator-(const mod_int &a, const mod_int &b) { return mod_int(a) -= b; }
  59. friend mod_int operator*(const mod_int &a, const mod_int &b) { return mod_int(a) *= b; }
  60. friend mod_int operator/(const mod_int &a, const mod_int &b) { return mod_int(a) /= b; }
  61.  
  62. mod_int& operator++() {
  63. val = val == MOD - 1 ? 0 : val + 1;
  64. return *this;
  65. }
  66.  
  67. mod_int& operator--() {
  68. val = val == 0 ? MOD - 1 : val - 1;
  69. return *this;
  70. }
  71.  
  72. mod_int operator++(int) { mod_int before = *this; ++*this; return before; }
  73. mod_int operator--(int) { mod_int before = *this; --*this; return before; }
  74.  
  75. mod_int operator-() const {
  76. return val == 0 ? 0 : MOD - val;
  77. }
  78.  
  79. bool operator==(const mod_int &other) const { return val == other.val; }
  80. bool operator!=(const mod_int &other) const { return val != other.val; }
  81.  
  82. mod_int inv() const {
  83. return mod_inv(val);
  84. }
  85.  
  86. mod_int pow(long long p) const {
  87. assert(p >= 0);
  88. mod_int a = *this, result = 1;
  89.  
  90. while (p > 0) {
  91. if (p & 1)
  92. result *= a;
  93.  
  94. a *= a;
  95. p >>= 1;
  96. }
  97.  
  98. return result;
  99. }
  100.  
  101. friend ostream& operator<<(ostream &stream, const mod_int &m) {
  102. return stream << m.val;
  103. }
  104. };
  105.  
  106. const int N = 1505;
  107. char s[N], bad[30];
  108. int k;
  109.  
  110. struct Hash {
  111. vector<mod_int> H, pre;
  112. Hash(char *s, int N) {
  113. H.resize(N+1);
  114. pre.resize(N+1);
  115. mod_int base = rand(35, 1<<10);
  116. // cout << base << '\n';
  117. pre[0] = 1;
  118. mod_int cur = 0;
  119. for (int i = 1; i <= N; ++i) {
  120. pre[i] = pre[i-1] * base;
  121. cur = cur * base + (s[i] - 'a' + 1);
  122. H[i] = cur;
  123. // cout << cur << ' ';
  124. }
  125. // cout << endl;
  126. }
  127. unsigned get_hash(int l, int r) {
  128. mod_int rem = pre[r-l+1] * H[l-1];
  129. return mod_int(H[r] - rem).val;
  130. }
  131.  
  132. };
  133.  
  134. signed main() {
  135. ios::sync_with_stdio(false);
  136. cin.tie(0);
  137. cin >> s+1 >> bad >> k;
  138. int N = strlen(s+1);
  139. Hash ins1(s, N), ins2(s, N);
  140. // cout << endl;
  141. for (int i = 1; i <= N; i += 2) {
  142. // cout << ins1.get_hash(i,i+1) << ' ' << ins2.get_hash(i,i+1) << '\n';
  143. }
  144. set<pair<unsigned,unsigned>> st;
  145. // set<unsigned> st1, st2;
  146. for (int i = 1; i <= N; ++i) {
  147. int badTillNow = 0;
  148. for (int j = i; j <= N; ++j) {
  149. badTillNow += bad[s[j]-'a'] == '0';
  150. if (badTillNow > k) {
  151. break;
  152. }
  153. st.insert(make_pair(ins1.get_hash(i, j), ins2.get_hash(i,j)));
  154. // st1.insert(ins1.get_hash(i,j));
  155. // st2.insert(ins2.get_hash(i,j));
  156. }
  157. }
  158. cout << st.size() << '\n';//min(st1.size(), st2.size());
  159. return 0;
  160. }
  161. // 1). Try forming/rearranging the equations if any
  162. // 2). If problem asks to count, try counting in reverse(it can be easier sometimes)
Add Comment
Please, Sign In to add comment