tuki2501

voi17virus.cpp

Nov 1st, 2021 (edited)
1,019
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 2.60 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3.  
  4. #define hash myHash
  5. typedef long long ll;
  6.  
  7. const int K = 15;
  8. const int N = 3005;
  9.  
  10. const int BASE = 311;
  11. const ll  MOD  = 1e9 + 7;
  12.  
  13. int n, q; string s;
  14. int query[K], ans[K];
  15. ll hash[N], basePow[N];
  16. int f[N][N], dp[2][N][N];
  17.  
  18. void chmax(int &a, int b) {
  19.   if (a < b) a = b;
  20. }
  21.  
  22. ll getHash(int l, int r) {
  23.   return (hash[r] - (hash[l - 1] * basePow[r - l + 1]) % MOD + MOD) % MOD;
  24. }
  25.  
  26. namespace sub1 {
  27.   void Main() {
  28.     for (int i = 1; i + 1 <= n; i++)
  29.     for (int j = i + 1; j <= n; j++) {
  30.       if (j + (j - i) - 1 > n) continue;
  31.       int cnt = 0;
  32.       for (int k = 1; i + k - 1 < j; k++) {
  33.         if (s[i + k - 1] != s[j + k - 1]) cnt++;
  34.       }
  35.       if (cnt <= 10) chmax(ans[cnt], j - i);
  36.     }
  37.     for (int i = 1; i <= 10; i++) {
  38.       chmax(ans[i], ans[i - 1]);
  39.     }
  40.   }
  41. };
  42.  
  43. namespace sub2 {
  44.   void Main() {
  45.     for (int i = 1; i + 1 <= n; i++)
  46.     for (int j = i + 1; j <= n; j++) {
  47.       int len = j - i;
  48.       if (j + len - 1 > n) continue;
  49.       if (getHash(i, i + len - 1) == getHash(j, j + len - 1)) {
  50.         chmax(ans[0], j - i);
  51.       }
  52.     }
  53.   }
  54. };
  55.  
  56. namespace sub3 {
  57.   void Main() {
  58.     for (int i = 1; i + 1 <= n; i++)
  59.     for (int j = i + 1; j <= n; j++) {
  60.       int l = 1, r = n - j + 1;
  61.       while (l <= r) {
  62.         int x = (l + r) / 2;
  63.         if (i + x - 1 <= n && j + x - 1 <= n && getHash(i, i + x - 1) == getHash(j, j + x - 1)) {
  64.           f[i][j] = dp[0][i][j] = x;
  65.           l = x + 1;
  66.         }
  67.         else r = x - 1;
  68.       }
  69.       if (f[i][j] >= j - i) chmax(ans[0], j - i);
  70.     }
  71.     for (int k = 1; k <= 10; k++) {
  72.       for (int i = 1; i + 1 <= n; i++)
  73.       for (int j = i + 1; j <= n; j++) {
  74.         int len = dp[(k + 1) % 2][i][j];
  75.         int si = i + len;
  76.         int sj = j + len;
  77.         if (si > n || sj > n) {
  78.           dp[k % 2][i][j] = len;
  79.         }
  80.         else {
  81.           dp[k % 2][i][j] = len + 1 + f[si + 1][sj + 1];
  82.         }
  83.         if (dp[k % 2][i][j] >= j - i) chmax(ans[k], j - i);
  84.       }
  85.     }
  86.   }
  87. };
  88.  
  89. signed main() {
  90.   cin.tie(0)->sync_with_stdio(0);
  91.   cin >> q >> s;
  92.   n = s.size();
  93.   s = '#' + s;
  94.   bool all_zero = true;
  95.   for (int i = 1; i <= q; i++) {
  96.     cin >> query[i];
  97.     if (query[i]) all_zero = false;
  98.   }
  99.   basePow[0] = 1;
  100.   for (int i = 1; i <= n; i++) {
  101.     hash[i] = (hash[i - 1] * BASE + s[i]) % MOD;
  102.     basePow[i] = (basePow[i - 1] * BASE) % MOD;
  103.   }
  104.   if (n <= 300) sub1::Main();
  105.   else if (n <= 3000 && all_zero) sub2::Main();
  106.   else sub3::Main();
  107.   for (int i = 1; i <= q; i++) {
  108.     cout << ans[query[i]] << '\n';
  109.   }
  110. }
  111.  
Advertisement
Add Comment
Please, Sign In to add comment