Advertisement
Caaaaaaat

Suffix Solution

Apr 1st, 2025 (edited)
553
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.18 KB | None | 0 0
  1. #include<bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int pls(int a, int b, int MOD) {
  6.     a += b;
  7.     if (a >= MOD) a -= MOD;
  8.     return a;
  9. }
  10.  
  11. int mns(int a, int b, int MOD) {
  12.     a -= b;
  13.     if (a < 0) a += MOD;
  14.     return a;
  15. }
  16.  
  17. int prd(int a, int b, int MOD) {
  18.     return 1ll * a * b % MOD;
  19. }
  20.  
  21. const pair<int, int> mods = {1e9 + 7, 998244353}, bases = {179, 239};
  22.  
  23. pair<int, int> operator+(pair<int, int> a, pair<int, int> b) {
  24.     return make_pair(
  25.             pls(a.first, b.first, mods.first),
  26.             pls(a.second, b.second, mods.second)
  27.             );
  28. }
  29.  
  30. pair<int, int> operator-(pair<int, int> a, pair<int, int> b) {
  31.     return make_pair(
  32.             mns(a.first, b.first, mods.first),
  33.             mns(a.second, b.second, mods.second)
  34.     );
  35. }
  36.  
  37. pair<int, int> operator*(pair<int, int> a, pair<int, int> b) {
  38.     return make_pair(
  39.             prd(a.first, b.first, mods.first),
  40.             prd(a.second, b.second, mods.second)
  41.     );
  42. }
  43.  
  44. struct MyHash {
  45.     vector<pair<int, int>> pref, pw;
  46.     string s;
  47.     int n;
  48.  
  49.     MyHash(string &_s) {
  50.         s = _s;
  51.         n = (int) s.size();
  52.         pref.resize(n + 1, {0, 0});
  53.         pw.resize(n + 1, {1, 1});
  54.         for (int i = 1; i <= n; i++) {
  55.             auto val = (int)(s[i - 1] - 'A' + 1);
  56.             pref[i] = pref[i - 1] * bases + make_pair(val, val);
  57.             pw[i] = pw[i - 1] * bases;
  58.         }
  59.     }
  60.  
  61.     pair<int, int> ask(int l, int r) {
  62.         return pref[r] - pref[l] * pw[r - l];
  63.     }
  64. };
  65.  
  66. int hashesSolution(string &s) {
  67.     string rev = s;
  68.     reverse(rev.begin(), rev.end());
  69.     MyHash HashS(s), HashRev(rev);
  70.     int cnt = 0, N = (int) s.size();
  71.     for (int len = 0; len <= N; len++) {
  72.         if (HashS.ask(N - len, N) == HashS.ask(0, len) &&
  73.             HashS.ask(len, N) == HashRev.ask(0, N - len)) {
  74.             cnt++;
  75.         }
  76.     }
  77.     return cnt;
  78. }
  79.  
  80. int stupidSolution(string &s) {
  81.     int cnt = 0;
  82.     int N = (int) s.size();
  83.     string rev = s;
  84.     reverse(rev.begin(), rev.end());
  85.     for (int len = 0; len <= N; len++) {
  86.         string t;
  87.         for (int i = N - len; i < N; i++) t += s[i];
  88.         t += rev;
  89.         bool fl = true;
  90.         for (int i = 0; i < (int)t.size() / 2; i++) {
  91.             if (t[i] != t[(int)t.size() - i - 1]) {
  92.                 fl = false;
  93.                 break;
  94.             }
  95.         }
  96.         cnt += (int) fl;
  97.     }
  98.     return cnt;
  99. }
  100.  
  101. mt19937 rnd(time(nullptr));
  102.  
  103. string getRandomString(int len) {
  104.     string res;
  105.     for (int i = 0; i < len; i++) {
  106.         int val = rnd();
  107.         val = abs(val) % 52;
  108.         if (val < 26) res += (char)(val + 'A');
  109.         else res += (char)(val - 26 + 'a');
  110.     }
  111.     return res;
  112. }
  113.  
  114. string correct(string &s) {
  115.     string t;
  116.     if (s.empty()) return "#";
  117.     t += s[0];
  118.     for (int i = 1; i < (int) s.size(); i++) {
  119.         t += '#';
  120.         t += s[i];
  121.     }
  122.     return t;
  123. }
  124.  
  125. vector<int> manacher(string &s) {
  126.     int n = (int) s.size();
  127.     vector<int> d(n, 1);
  128.     int l = 0, r = 0;
  129.     for (int i = 1; i < n; i++) {
  130.         if (i < r)
  131.             d[i] = min(r - i + 1, d[l + r - i]);
  132.         while (i - d[i] >= 0 && i + d[i] < n && s[i - d[i]] == s[i + d[i]])
  133.             d[i]++;
  134.         if (i + d[i] - 1 > r)
  135.             l = i - d[i] + 1, r = i + d[i] - 1;
  136.     }
  137.     return d;
  138. }
  139.  
  140. int manacherSolution(string &s) {
  141.     string rev = s;
  142.     reverse(rev.begin(), rev.end());
  143.     string t = rev + s;
  144.     t = correct(t);
  145.     auto d = manacher(t);
  146.     int cnt = 0, n = (int) t.size();
  147.     for (int i = n / 2; i < n; i++) {
  148.         if (i + d[i] == n && i - d[i] <= n / 2) {
  149.             cnt++;
  150.         }
  151.     }
  152.     return cnt;
  153. }
  154.  
  155. void Fast() {
  156.     cin.tie(nullptr);
  157.     ios_base::sync_with_stdio(false);
  158. }
  159.  
  160. signed main() {
  161.     Fast();
  162.     string s;
  163.     cin >> s;
  164.     cout << manacherSolution(s);
  165. //    for (int len = 0; len <= 500; len++) {
  166. //        for (int i = 0; i < 100; i++) {
  167. //            string s = getRandomString(len);
  168. //            int answer = hashesSolution(s), result = manacherSolution(s);
  169. //            if (answer != result) {
  170. //                cout << s << "\n" << result << " " << answer << endl;
  171. //            }
  172. //        }
  173. //    }
  174. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement