danielvitor23

B

Nov 2nd, 2021 (edited)
782
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.55 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. const uint64_t MOD = (1LL<<61)-1;
  5. const int base = 31;
  6. const int MAX = 100005;
  7.  
  8. uint64_t p[MAX];
  9.  
  10. uint64_t modMul(uint64_t a, uint64_t b){
  11.   uint64_t l1 = (uint32_t)a, h1 = a>>32, l2 = (uint32_t)b, h2 = b>>32;
  12.   uint64_t l = l1*l2, m = l1*h2 + l2*h1, h = h1*h2;
  13.   uint64_t ret = (l&MOD) + (l>>61) + (h << 3) + (m >> 29) + ((m << 35) >> 3) + 1;
  14.   ret = (ret & MOD) + (ret>>61);
  15.   ret = (ret & MOD) + (ret>>61);
  16.   return ret-1;
  17. }
  18.  
  19. struct StringHashing {
  20.     inline int getInt(char c) {
  21.         return (c == '#' ? 27 : c-'a'+1);
  22.     }
  23.     /*
  24.         hs[i] = s[0]*p^(i) + s[1]*p(i-1) + ... + s[i-1]*p + s[i]
  25.     */
  26.     vector<uint64_t> hs;
  27.     StringHashing () {}
  28.     StringHashing (const string &s) {
  29.         int n = s.size();
  30.         hs.resize(n);
  31.         hs[0] = getInt(s[0]);
  32.         for (int i = 1; i < n; ++i) {
  33.             hs[i] = modMul(hs[i-1], base) + getInt(s[i]);
  34.       if (hs[i] >= MOD) {
  35.         hs[i] -= MOD;
  36.       }
  37.         }
  38.     }
  39.     /*
  40.         hs[i..j] = hs[j] - hs[i-1] * p^(j-i+1)
  41.     */
  42.     uint64_t getValue(int l, int r) {
  43.         if (l > r) return -1;
  44.         uint64_t res = hs[r];
  45.     if (l > 0) {
  46.       res -= modMul(p[r-l+1], hs[l-1]);
  47.       if (res < 0) {
  48.         res += MOD;
  49.       }
  50.     }
  51.         return res;
  52.     }
  53. };
  54.  
  55. int n, m;
  56. string a, aux;
  57. vector<string> s;
  58. vector<uint64_t> vec;
  59. StringHashing sh, sh1;
  60.  
  61. bool f(int k) {
  62.   vec.clear();
  63.   for (int i = 0; i < (int)aux.size()-k+1; ++i) {
  64.     vec.push_back(sh1.getValue(i, i+k-1));
  65.   }
  66.  
  67.   sort(vec.begin(), vec.end());
  68.   vec.erase(unique(vec.begin(), vec.end()), vec.end());
  69.  
  70.   vector<int> vet(2*n+1, 0);
  71.  
  72.   for (int i = 0; i < 2*n-k+1; ++i) {
  73.     if (binary_search(vec.begin(), vec.end(), sh.getValue(i, i+k-1))) {
  74.       int l = max(0, i+k-n), r = i;
  75.       ++vet[l];
  76.       --vet[r+1];
  77.     }
  78.   }
  79.  
  80.   for (int i = 1; i <= 2*n; ++i) {
  81.     vet[i] += vet[i-1];
  82.   }
  83.  
  84.   bool ok = true;
  85.   for (int i = 0; i < n; ++i) {
  86.     ok &= (vet[i]+vet[i+n] > 0);
  87.   }
  88.  
  89.   return ok;
  90. }
  91.  
  92. int main() {
  93.   cin.tie(0)->sync_with_stdio(0);
  94.  
  95.   p[0] = 1;
  96.   for (int i = 1; i < MAX; ++i) {
  97.     p[i] = modMul(p[i-1], base);
  98.   }
  99.  
  100.   cin >> n >> m;
  101.   cin >> a;
  102.   a += a;
  103.  
  104.   s.resize(m);
  105.   int lo = 1, hi = 0, mid = -1, ans = 0;
  106.   for (int i = 0; i < m; ++i) {
  107.     cin >> s[i];
  108.     hi = max(hi, (int)s[i].size());
  109.   }
  110.   hi = min(hi, n);
  111.  
  112.   for (string &sr : s) {
  113.     aux += '#' + sr;
  114.   }
  115.  
  116.   sh1 = StringHashing(aux);
  117.   sh = StringHashing(a);
  118.  
  119.   while (lo <= hi) {
  120.     mid = (lo + hi) / 2;
  121.     if (f(mid)) {
  122.       ans = mid;
  123.       lo = mid+1;
  124.     } else {
  125.       hi = mid-1;
  126.     }
  127.   }
  128.  
  129.   cout << ans << '\n';
  130. }
Add Comment
Please, Sign In to add comment