Problem p04018 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <algorithm>
#include <bitset>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop                                                                   \
  char nyaa;                                                                   \
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-11;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
typedef pair<ld, ld> LDP;
typedef unsigned long long ul;
string s;
vector<int> d;
const int mn = 500001;
bool leok[mn], riok[mn];
bool lesk[mn], risk[mn];
int main() {
  cin >> s;
  int n = s.length();
  int k = sqrt(n + 0.1);
  rep1(i, k) {
    if (n % i != 0)
      continue;
    d.push_back(i);
    d.push_back(n / i);
  }
  sort(d.begin(), d.end());
  int len = unique(d.begin(), d.end()) - d.begin();
  int m = n;
  rep(i, len) {
    int l = d[i];
    int r = n / l;
    bool valid = true;
    rep(j, r - 1) {
      string le = s.substr(j * l, l);
      string ri = s.substr((j + 1) * l, l);
      if (le != ri) {
        valid = false;
        break;
      }
    }
    if (valid) {
      m = l;
      break;
    }
  }
  if (m == 1) {
    cout << n << endl << 1 << endl;
  } else if (m == n) {
    cout << 1 << endl << 1 << endl;
  } else {
    if (m != 2) {
      fill(leok, leok + n + 1, true);
      fill(riok, riok + n + 1, true);
      for (int i = 2 * m; i <= n; i += m) {
        leok[i] = false;
        lesk[i] = true;
      }
      for (int i = n - 2 * m; i >= 0; i -= m) {
        riok[i] = false;
        risk[i] = true;
      }
      rep1(i, n) {
        if (lesk[i])
          continue;
        else {
          int le = 0, ri = i;
          while (ri + i <= n) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[ri + j]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              ri += i;
              le += i;
              leok[ri] = false;
              lesk[ri] = true;
            } else {
              lesk[ri] = true;
              break;
            }
          }
        }
      }
      rep1(i, n) {
        if (risk[n - i])
          continue;
        else {
          int le = n - i, ri = n;
          while (le - i >= 0) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[le + j - i]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              le -= i;
              ri -= i;
              riok[le] = false;
              risk[le] = true;
            } else {
              risk[le] = true;
              break;
            }
          }
        }
      }
      int cnt = 0;
      rep1(i, n) {
        if (leok[i] && riok[i])
          cnt++;
      }
      cout << 2 << endl;
      cout << cnt << endl;
    } else {
      fill(leok, leok + m + 1, true);
      fill(riok, riok + m + 1, true);
      rep1(i, m) {
        if (lesk[i])
          continue;
        else {
          int le = 0, ri = i;
          while (ri + i <= m) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[ri + j]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              ri += i;
              le += i;
              leok[ri] = false;
              lesk[ri] = true;
            } else {
              lesk[ri] = true;
              break;
            }
          }
        }
      }
      rep1(i, m) {
        if (risk[m - i])
          continue;
        else {
          int le = m - i, ri = m;
          while (le - i >= 0) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[le + j - i]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              le -= i;
              ri -= i;
              riok[le] = false;
              risk[le] = true;
            } else {
              risk[le] = true;
              break;
            }
          }
        }
      }
      int cnt = 0;
      int r = n / m;
      cnt += (r - 2) * (m - 1);
      if (r == 2)
        cnt++;
      rep1(i, m - 1) {
        if (leok[i])
          cnt++;
      }
      rep1(i, m - 1) {
        if (riok[i])
          cnt++;
      }
      cout << 2 << endl;
      cout << cnt << endl;
    }
  }
  // stop
  return 0;
}


Fixed submission:
#include <algorithm>
#include <bitset>
#include <ciso646>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>
using namespace std;
typedef long long ll;
typedef unsigned int ui;
const ll mod = 1000000007;
const ll INF = (ll)1000000007 * 1000000007;
typedef pair<int, int> P;
#define stop                                                                   \
  char nyaa;                                                                   \
  cin >> nyaa;
#define rep(i, n) for (int i = 0; i < n; i++)
#define per(i, n) for (int i = n - 1; i >= 0; i--)
#define Rep(i, sta, n) for (int i = sta; i < n; i++)
#define rep1(i, n) for (int i = 1; i <= n; i++)
#define per1(i, n) for (int i = n; i >= 1; i--)
#define Rep1(i, sta, n) for (int i = sta; i <= n; i++)
typedef long double ld;
typedef complex<ld> Point;
const ld eps = 1e-11;
const ld pi = acos(-1.0);
typedef pair<ll, ll> LP;
typedef pair<ld, ld> LDP;
typedef unsigned long long ul;
string s;
vector<int> d;
const int mn = 500001;
bool leok[mn], riok[mn];
bool lesk[mn], risk[mn];
int main() {
  cin >> s;
  int n = s.length();
  int k = sqrt(n + 0.1);
  rep1(i, k) {
    if (n % i != 0)
      continue;
    d.push_back(i);
    d.push_back(n / i);
  }
  sort(d.begin(), d.end());
  int len = unique(d.begin(), d.end()) - d.begin();
  int m = n;
  rep(i, len) {
    int l = d[i];
    int r = n / l;
    bool valid = true;
    rep(j, r - 1) {
      string le = s.substr(j * l, l);
      string ri = s.substr((j + 1) * l, l);
      if (le != ri) {
        valid = false;
        break;
      }
    }
    if (valid) {
      m = l;
      break;
    }
  }
  if (m == 1) {
    cout << n << endl << 1 << endl;
  } else if (m == n) {
    cout << 1 << endl << 1 << endl;
  } else {
    if (n <= 400000) {
      fill(leok, leok + n + 1, true);
      fill(riok, riok + n + 1, true);
      for (int i = 2 * m; i <= n; i += m) {
        leok[i] = false;
        lesk[i] = true;
      }
      for (int i = n - 2 * m; i >= 0; i -= m) {
        riok[i] = false;
        risk[i] = true;
      }
      rep1(i, n) {
        if (lesk[i])
          continue;
        else {
          int le = 0, ri = i;
          while (ri + i <= n) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[ri + j]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              ri += i;
              le += i;
              leok[ri] = false;
              lesk[ri] = true;
            } else {
              lesk[ri] = true;
              break;
            }
          }
        }
      }
      rep1(i, n) {
        if (risk[n - i])
          continue;
        else {
          int le = n - i, ri = n;
          while (le - i >= 0) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[le + j - i]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              le -= i;
              ri -= i;
              riok[le] = false;
              risk[le] = true;
            } else {
              risk[le] = true;
              break;
            }
          }
        }
      }
      int cnt = 0;
      rep1(i, n) {
        if (leok[i] && riok[i])
          cnt++;
      }
      cout << 2 << endl;
      cout << cnt << endl;
    } else {
      fill(leok, leok + m + 1, true);
      fill(riok, riok + m + 1, true);
      rep1(i, m) {
        if (lesk[i])
          continue;
        else {
          int le = 0, ri = i;
          while (ri + i <= m) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[ri + j]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              ri += i;
              le += i;
              leok[ri] = false;
              lesk[ri] = true;
            } else {
              lesk[ri] = true;
              break;
            }
          }
        }
      }
      rep1(i, m) {
        if (risk[m - i])
          continue;
        else {
          int le = m - i, ri = m;
          while (le - i >= 0) {
            bool valid = true;
            rep(j, i) {
              if (s[le + j] != s[le + j - i]) {
                valid = false;
                break;
              }
            }
            if (valid) {
              le -= i;
              ri -= i;
              riok[le] = false;
              risk[le] = true;
            } else {
              risk[le] = true;
              break;
            }
          }
        }
      }
      int cnt = 0;
      int r = n / m;
      cnt += (r - 2) * (m - 1);
      if (r == 2)
        cnt++;
      rep1(i, m - 1) {
        if (leok[i])
          cnt++;
      }
      rep1(i, m - 1) {
        if (riok[i])
          cnt++;
      }
      cout << 2 << endl;
      cout << cnt << endl;
    }
  }
  // stop
  return 0;
}