Advertisement
Mlxa

### Прямой и обратный хеш по двум(H) модулям

Feb 17th, 2019
162
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.27 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. #define long ll
  5. #define all(x) begin(x), end(x)
  6.  
  7. const int N = 1e6;
  8. const int P = 257;
  9. const int H = 2;
  10. const uint64_t M[H] = {(uint64_t)1e9 + 21, (uint64_t)1e9 + 33};
  11. uint64_t p_pow[H][N];
  12.  
  13. struct Initialization {
  14.     Initialization() {
  15.         for (int k = 0; k < H; ++k) {
  16.             p_pow[k][0] = 1;
  17.             for (int i = 1; i < N; ++i) {
  18.                 p_pow[k][i] = (p_pow[k][i - 1] * P) % M[k];
  19.             }
  20.         }
  21.     }
  22. } init;
  23.  
  24. struct Forward_Multiple_Hash {
  25.     int n;
  26.     string s;
  27.     vector<uint64_t> h[H];
  28.    
  29.     Forward_Multiple_Hash(const string &from) :
  30.         n((int)from.size()),
  31.         s(from) {
  32.         for (int k = 0; k < H; ++k) {
  33.             h[k] = {0};
  34.             h[k].reserve(n + 1);
  35.             for (char c : s) {
  36.                 h[k].push_back((h[k].back() * P + c) % M[k]);
  37.             }
  38.         }
  39.     }
  40.    
  41.     long operator()(int l, int r) {
  42.         //assert(0 <= l && l <= r && r <= n - 1);
  43.         static uint64_t a[H];
  44.         for (int k = 0; k < H; ++k) {
  45.             a[k] = (h[k][r + 1] + (M[k] << 32) - h[k][l] * p_pow[k][r - l + 1]) % M[k];
  46.         }
  47.         return (a[0] << 32) + a[1];
  48.     }
  49. };
  50.  
  51. struct Backward_Multiple_Hash {
  52.     int n;
  53.     string s;
  54.     vector<uint64_t> h[H];
  55.    
  56.     Backward_Multiple_Hash(const string &from) :
  57.         n((int)from.size()),
  58.         s(from) {
  59.         reverse(all(s));
  60.         for (int k = 0; k < H; ++k) {
  61.             h[k] = {0};
  62.             h[k].reserve(n + 1);
  63.             for (char c : s) {
  64.                 h[k].push_back((h[k].back() * P + c) % M[k]);
  65.             }
  66.         }
  67.     }
  68.    
  69.     long operator()(int revl, int revr) {
  70.         //assert(0 <= revl && revl <= revr && revr <= n - 1);
  71.         int l = n - 1 - revr, r = n - 1 - revl;
  72.         //assert(0 <= l && l <= r && r <= n - 1);
  73.         static uint64_t a[H];
  74.         for (int k = 0; k < H; ++k) {
  75.             a[k] = (h[k][r + 1] + (M[k] << 32) - h[k][l] * p_pow[k][r - l + 1]) % M[k];
  76.         }
  77.         return (a[0] << 32) + a[1];
  78.     }
  79. };
  80.  
  81. int main() {
  82. #ifdef LC
  83.     assert(freopen("input.txt", "r", stdin));
  84. #endif
  85.     ios::sync_with_stdio(false);
  86.     cin.tie(nullptr);
  87.    
  88.     string s;
  89.     cin >> s;
  90.     Forward_Multiple_Hash fw(s);
  91.    
  92.     int n = (int)s.size();
  93.    
  94.     const int S = 50e6;
  95.     static long hs[S];
  96.     size_t ptr = 0;
  97.    
  98.     for (int i = 0; i < n; ++i) {
  99.         for (int j = i; j < n; ++j) {
  100.             hs[ptr++] = fw(i, j);
  101.         }
  102.     }
  103.    
  104.     cout << clock() * 1000 / CLOCKS_PER_SEC << endl;
  105.    
  106.     sort(hs, hs + ptr);
  107.     ptr = unique(hs, hs + ptr) - hs;
  108.    
  109.     cout << ptr << endl;
  110.     return 0;
  111. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement