danielvitor23

MAXMATCH - Maximum Self-Matching

Aug 1st, 2023
1,424
0
Never
1
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.03 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. typedef long long ll;
  4. typedef pair<int,int> pii;
  5. typedef pair<ll, ll> pll;
  6. struct complex_t {
  7.   double a {0.0}, b {0.0};
  8.   complex_t(){}
  9.   complex_t(double na) : a{na}{}  
  10.   complex_t(double na, double nb) : a{na}, b{nb} {}  
  11.   const complex_t operator+(const complex_t &c) const {
  12.     return complex_t(a + c.a, b + c.b);
  13.   }
  14.   const complex_t operator-(const complex_t &c) const {
  15.     return complex_t(a - c.a, b - c.b);
  16.   }
  17.   const complex_t operator*(const complex_t &c) const {
  18.     return complex_t(a*c.a - b*c.b, a*c.b + b*c.a);
  19.   }
  20.   const complex_t operator/(const int &c) const {
  21.     return complex_t(a/c, b/c);
  22.   }
  23. };
  24. using cd = complex_t;
  25. const double PI = acos(-1);
  26. void fft(vector<cd> & a, bool invert) {
  27.   int n = a.size();
  28.   for (int i = 1, j = 0; i < n; i++) {
  29.     int bit = n >> 1;
  30.     for (; j & bit; bit >>= 1)
  31.       j ^= bit;
  32.     j ^= bit;
  33.     if (i < j)
  34.       swap(a[i], a[j]);
  35.   }
  36.   for (int len = 2; len <= n; len <<= 1) {
  37.     double ang = 2 * PI / len * (invert ? -1 : 1);
  38.     cd wlen(cos(ang), sin(ang));
  39.     for (int i = 0; i < n; i += len) {
  40.       cd w(1);
  41.       for (int j = 0; j < len / 2; j++) {
  42.         cd u = a[i+j], v = a[i+j+len/2] * w;
  43.         a[i+j] = u + v;
  44.         a[i+j+len/2] = u - v;
  45.         w = w * wlen;
  46.       }
  47.     }
  48.   }
  49.   if (invert) {
  50.     for (cd & x : a){
  51.       x = x / n;
  52.     }
  53.   }
  54. }
  55. vector<ll> multiply(vector<int> const& a, vector<int> const& b) {
  56.   vector<cd> fa(a.begin(), a.end());
  57.   vector<cd> fb(b.begin(), b.end());  
  58.   int n = 1;
  59.   while(n < int(a.size() + b.size()) )
  60.     n <<= 1;    
  61.   fa.resize(n);
  62.   fb.resize(n);
  63.   fft(fa, false);
  64.   fft(fb, false);  
  65.   for (int i = 0; i < n; i++)
  66.     fa[i] = fa[i]*fb[i];  
  67.   fft(fa, true);
  68.   vector<ll> result(n);
  69.   for (int i = 0; i < n; i++)
  70.     result[i] = round(fa[i].a);
  71.   return result;
  72. }
  73.  
  74. vector<long long> getC(string s, char ch) {
  75.   int n = s.size();
  76.  
  77.   vector<int> a(n, 0), b(n, 0);
  78.   for (int i = 0; i < n; ++i) {
  79.     if (s[i] == ch) {
  80.       a[i] = 1;
  81.       b[i] = 1;
  82.     }
  83.   }
  84.  
  85.   reverse(a.begin(), a.end());
  86.   for (int i = 0; i < n; ++i) {
  87.     a.push_back(0);
  88.   }
  89.  
  90.   for (int i = 0; i < n; ++i) {
  91.     b.push_back(b[i]);
  92.   }
  93.  
  94.   vector<long long> c = multiply(a, b);
  95.  
  96.   // for (int i = 0; i < (int)c.size(); ++i) {
  97.   //   cout << c[i] << " \n"[i==(int)c.size()-1];
  98.   // }
  99.  
  100.   return c;
  101. }
  102.  
  103. int main() {
  104.   cin.tie(0)->sync_with_stdio(0);
  105.  
  106.   string s; cin >> s;
  107.   int n = s.size();
  108.  
  109.   vector<long long> c1 = getC(s, 'a');
  110.   vector<long long> c2 = getC(s, 'b');
  111.   vector<long long> c3 = getC(s, 'c');
  112.  
  113.   long long mx = 0;
  114.   for (int i = 2 * n; i < 2 * n + n - 1; ++i) {
  115.     //cout << c1[i] << '\n';
  116.     mx = max(mx, c1[i] + c2[i] + c3[i]);
  117.   }
  118.  
  119.   vector<int> ans;
  120.   for (int i = 2 * n, j = 1; i < 2 * n + n - 1; ++i, ++j) {
  121.     if (mx == c1[i] + c2[i] + c3[i]) {
  122.       ans.push_back(j);
  123.     }
  124.   }
  125.  
  126.   cout << mx << '\n';
  127.   for (int i = 0; i < (int)ans.size(); ++i) {
  128.     cout << ans[i] << " \n"[i==(int)ans.size()-1];
  129.   }
  130. }
Advertisement
Comments
Add Comment
Please, Sign In to add comment