Advertisement
milon34

string hashing with pair

Feb 23rd, 2023
57
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.71 KB | None | 0 0
  1. problem link:https://cses.fi/problemset/task/1753/
  2.  
  3. #include <bits/stdc++.h>
  4. using namespace std;
  5. #define ll long long int
  6. const int mx = 1e6 + 5;
  7. pair<int, int> pw[mx + 5], invPw[mx + 5];
  8. inline void normal(ll &a, ll MOD) {
  9.     a %= MOD;
  10.     (a < 0) && (a += MOD);
  11. }
  12. inline ll modMul(ll a, ll b, ll MOD) {
  13.     a %= MOD, b %= MOD;
  14.     normal(a, MOD), normal(b, MOD);
  15.     return (a * b) % MOD;
  16. }
  17. inline ll modPow(ll b, ll p, ll MOD) {
  18.     ll r = 1;
  19.     while (p) {
  20.         if (p & 1)
  21.             r = modMul(r, b, MOD);
  22.         b = modMul(b, b, MOD);
  23.         p >>= 1;
  24.     }
  25.     return r;
  26. }
  27. inline ll modInverse(ll a, ll MOD) { return modPow(a, MOD - 2, MOD); }
  28. int p1 = 31, p2 = 37, MOD1 = 1e9 + 7, MOD2 = 1e9 + 9;
  29. void pw_cal() {
  30.     pw[0] = {1, 1};
  31.     for (int i = 1; i <= mx; i++) {
  32.         pw[i].first = 1LL * pw[i - 1].first * p1 % MOD1;
  33.         pw[i].second = 1LL * pw[i - 1].second * p2 % MOD2;
  34.     }
  35.     int invp1 = modInverse(p1, MOD1);
  36.     int invp2 = modInverse(p2, MOD2);
  37.     invPw[0] = {1, 1};
  38.     for (int i = 1; i <= mx; i++) {
  39.         invPw[i].first = 1LL * invPw[i - 1].first * invp1 % MOD1;
  40.         invPw[i].second = 1LL * invPw[i - 1].second * invp2 % MOD2;
  41.     }
  42. }
  43. pair<int, int> string_hash(string s) {
  44.     pair<int, int> hs({0, 0});
  45.     for (int i = 0; i < s.size(); i++) {
  46.         hs.first += 1LL * (s[i] - 'a' + 1) * pw[i].first % MOD1;
  47.         hs.first %= MOD1;
  48.         hs.second += 1LL * (s[i] - 'a' + 1) * pw[i].second % MOD2;
  49.         hs.second %= MOD2;
  50.     }
  51.     return hs;
  52. }
  53. pair<int, int> pre[mx + 5];
  54. void build(string s) {
  55.     int n = s.size();
  56.     for (int i = 0; i < n; i++) {
  57.         pre[i].first = 1LL * (s[i] - 'a' + 1) * pw[i].first % MOD1;
  58.         pre[i].second = 1LL * (s[i] - 'a' + 1) * pw[i].second % MOD2;
  59.         if (i)pre[i].first = (pre[i].first + pre[i - 1].first) % MOD1;
  60.         if (i)pre[i].second = (pre[i].second + pre[i - 1].second) % MOD2;
  61.     }
  62. }
  63. pair<int, int> getHash(int i, int j) {
  64.     assert(i <= j);
  65.     pair<int, int> hs({0, 0});
  66.     hs.first = pre[j].first;
  67.     if (i)hs.first = (hs.first - pre[i - 1].first + MOD1) % MOD1;
  68.     hs.first = 1LL * hs.first * invPw[i].first % MOD1;
  69.     hs.second = pre[j].second;
  70.     if (i)hs.second = (hs.second - pre[i - 1].second + MOD2) % MOD2;
  71.     hs.second = 1LL * hs.second * invPw[i].second % MOD2;
  72.     return hs;
  73. }
  74. int32_t main() {
  75.     ios_base::sync_with_stdio(false);
  76.     cin.tie(0);
  77.     pw_cal();
  78.     string s1, s2;
  79.     cin >> s1 >> s2;
  80.     build(s1);
  81.     pair<int, int> check = string_hash(s2);
  82.     int cnt = 0;
  83.     int m = s2.size();
  84.     for (int i = 0; i + m - 1 < s1.size(); i++) {
  85.         cnt += getHash(i, i + m - 1) == check;
  86.     }
  87.     cout << cnt << endl;
  88.     return 0;
  89. }
  90.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement