BotByte

Hashing

Nov 14th, 2019
131
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.67 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define ll long long
  6. #define MAX 1200005
  7.  
  8. const ll base = 341;
  9. const ll mod = 1000000007;
  10.  
  11. ll po[MAX], inv[MAX];
  12.  
  13. ll bigMod(ll a, ll x)
  14. {
  15.     if(x == 0LL) return 1LL;
  16.     if(x == 1LL) return a;
  17.     ll ret = bigMod(a, x/2);
  18.     ret = (ret*ret)%mod;
  19.     if(x & 1LL) ret = (ret*a)%mod;
  20.     return ret;
  21. }
  22.  
  23. void gen()
  24. {
  25.     po[0] = 1;
  26.     for(int i=1; i<MAX; i++) po[i] = (po[i-1]*base)%mod;
  27.     inv[MAX-1] = bigMod(po[MAX-1], mod-2);
  28.     for(int i=MAX-2; i>=0; i--) inv[i] = (inv[i+1]*base)%mod;
  29. }
  30.  
  31. void genPrefixHash(string &str, vector<ll> &v)
  32. {
  33.     int n = (int) str.length();
  34.     ll sum = 0;
  35.     v.push_back(sum);
  36.     for(int i=0; i<n; i++){
  37.         sum += ((str[i]-'a')*po[i+1])%mod;
  38.         if(sum > mod) sum -= mod;
  39.         v.push_back(sum);
  40.     }
  41. }
  42.  
  43. ll substringHash(vector<ll> &prefixHash, int l, int r)
  44. {
  45.     ll sum = prefixHash[r]-prefixHash[l-1];
  46.     if(sum < 0) sum += mod;
  47.     sum = (sum*inv[l-1])%mod;
  48.     return sum;
  49. }
  50.  
  51. string text, pattern;
  52. vector<ll> textHash, patternHash;
  53.  
  54. void clr()
  55. {
  56.     text.clear();
  57.     pattern.clear();
  58.     textHash.clear();
  59.     patternHash.clear();
  60. }
  61.  
  62. int matched(int st, int l)
  63. {
  64.     int m = (int) pattern.length();
  65.     int best = l-1;
  66.     int low = l, high = st+m-1;
  67.     while(low <= high){
  68.         int mid = (low+high)/2;
  69.         ll textValue = substringHash(textHash, l, mid);
  70.         ll patternValue = substringHash(patternHash, l-st+1, mid-st+1);
  71.         if(textValue == patternValue){
  72.             best = mid;
  73.             low = mid+1;
  74.         }
  75.         else {
  76.             high = mid-1;
  77.         }
  78.     }
  79.     return best;
  80. }
  81.  
  82. bool calc(int st, int ed, int cur, int rem)
  83. {
  84.     if(rem < 0) return false;
  85.     cur = matched(st, cur+1);
  86.     if(rem != 0) cur++;
  87.     if(cur >= ed) return true;
  88.     return calc(st, ed, cur, rem-1);
  89. }
  90.  
  91. int main()
  92. {
  93.     //freopen("in.txt", "r", stdin);
  94.     ios_base::sync_with_stdio(false);
  95.     cin.tie(0);
  96.     gen();
  97.     int cases;
  98.     cin >> cases;
  99.     int caseno = 0;
  100.     while(cases--){
  101.         clr();
  102.         cin >> text >> pattern;
  103.         int k;
  104.         cin >> k;
  105.         genPrefixHash(text, textHash);
  106.         genPrefixHash(pattern, patternHash);
  107.         int n = (int) text.length();
  108.         int m = (int) pattern.length();
  109.         int ans = 0;
  110.         for(int i=1; i<=n-m+1; i++){
  111.             ll val1 = substringHash(textHash, i, i+m-1);
  112.             ll val2 = substringHash(patternHash, 1, m);
  113.         }
  114.         for(int i=1; i<=n-m+1; i++){
  115.             if(calc(i, i+m-1, i-1, k)){
  116.                 ans++;
  117.             }
  118.         }
  119.         cout << "Case " << ++caseno << ": " << ans << endl;
  120.     }
  121. }
Advertisement
Add Comment
Please, Sign In to add comment