Problem p04018 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int mod = 1e9 + 7;

class RollingHash {
public:
  typedef long long ll;
  ll B, mod; // B: ハッシュ基数
  int n;
  string s;
  vector<ll> hash;
  vector<ll> k;

  RollingHash() : n(-1){};
  RollingHash(string s, ll B = 1777771, ll mod = 1e9 + 7)
      : B(B), mod(mod), n(s.size()), s(s), hash(n + 1), k(n + 1) {
    for (int i = 0; i < n; i++)
      hash[i + 1] = (hash[i] * B % mod + s[i]) % mod;
    k[0] = 1;
    for (int i = 1; i <= n; i++)
      k[i] = (k[i - 1] * B) % mod;
  }

  ll get(int l, int r) { //[l, r)
    assert(0 <= l && r <= n && l <= r);
    return (mod + hash[r] - hash[l] * k[r - l] % mod) % mod;
  }

  // hash[a]とB.hash[b]からみて何文字一致してるか。
  int count(int a, RollingHash &B, int b) {
    int L = 0, R = min(n - a, B.n - b) + 1;
    while (L + 1 < R) {
      int M = (L + R) / 2;
      get(a, a + M) != B.get(b, b + M) ? R = M : L = M;
    }
    return L;
  }
};

typedef long long ll;

string s;

vector<ll> diviser(ll A) {

  vector<ll> res;

  for (ll i = 1; i * i <= A; i++)
    if (A % i == 0) {
      res.push_back(i);
      if (i * i != A)
        res.push_back(A / i);
    }

  sort(res.begin(), res.end());

  res.pop_back();

  return res;
}

bool check(int l, int r, int d, RollingHash rh) {
  if (r - l == 1)
    return true;
  return rh.get(l, r - d) == rh.get(l + d, r);
}

vector<vector<int>> d(500005);

signed main() {

  for (int i = 1; i <= 500000; i++) {

    for (int j = i * 2; j <= 500000; j += i) {

      d[j].push_back(i);
    }
  }

  cin >> s;

  int n = (int)s.size();

  int flg0 = 0;

  for (int i = 0; i < n; i++) {
    if (s[0] != s[i])
      flg0 = 1;
  }

  if (flg0 == 0) {
    cout << n << endl;
    cout << 1 << endl;
    return 0;
  }

  RollingHash rh(s);

  int flg = 0;

  for (int i = 0; i < (int)d[n].size(); i++) {
    if (check(0, n, d[n][i], rh) == true)
      flg = 1;
  }

  if (!flg) {
    cout << 1 << endl;
    cout << 1 << endl;
    return 0;
  }

  int ans = 0;

  for (int i = 0; i < n - 1; i++) {

    int flg1 = 0;

    for (int j = 0; j < (int)d[i + 1].size(); j++) {
      if (check(0, i + 1, d[i + 1][j], rh) == true)
        flg1 = 1;
    }

    int flg2 = 0;

    for (int j = 0; j < (int)d[n - i - 1].size(); j++) {
      if (check(i + 1, n, d[n - i - 1][j], rh) == true)
        flg2 = 1;
    }

    if (flg1 == 0 && flg2 == 0)
      ans++;
  }

  cout << 2 << endl;
  cout << ans << endl;

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int mod = 1e9 + 7;

class RollingHash {
public:
  typedef long long ll;
  ll B, mod; // B: ハッシュ基数
  int n;
  string s;
  vector<ll> hash;
  vector<ll> k;

  RollingHash() : n(-1){};
  RollingHash(string s, ll B = 1777771, ll mod = 1e9 + 7)
      : B(B), mod(mod), n(s.size()), s(s), hash(n + 1), k(n + 1) {
    for (int i = 0; i < n; i++)
      hash[i + 1] = (hash[i] * B % mod + s[i]) % mod;
    k[0] = 1;
    for (int i = 1; i <= n; i++)
      k[i] = (k[i - 1] * B) % mod;
  }

  ll get(int l, int r) { //[l, r)
    assert(0 <= l && r <= n && l <= r);
    return (mod + hash[r] - hash[l] * k[r - l] % mod) % mod;
  }

  // hash[a]とB.hash[b]からみて何文字一致してるか。
  int count(int a, RollingHash &B, int b) {
    int L = 0, R = min(n - a, B.n - b) + 1;
    while (L + 1 < R) {
      int M = (L + R) / 2;
      get(a, a + M) != B.get(b, b + M) ? R = M : L = M;
    }
    return L;
  }
};

typedef long long ll;

string s;

bool check(int l, int r, int d, RollingHash &rh) {
  if (r - l == 1)
    return true;
  return rh.get(l, r - d) == rh.get(l + d, r);
}

vector<vector<int>> d(500005);

signed main() {

  for (int i = 1; i <= 500000; i++) {

    for (int j = i * 2; j <= 500000; j += i) {

      d[j].push_back(i);
    }
  }

  cin >> s;

  int n = (int)s.size();

  int flg0 = 0;

  for (int i = 0; i < n; i++) {
    if (s[0] != s[i])
      flg0 = 1;
  }

  if (flg0 == 0) {
    cout << n << endl;
    cout << 1 << endl;
    return 0;
  }

  RollingHash rh(s);

  int flg = 0;

  for (int i = 0; i < (int)d[n].size(); i++) {
    if (check(0, n, d[n][i], rh) == true)
      flg = 1;
  }

  if (!flg) {
    cout << 1 << endl;
    cout << 1 << endl;
    return 0;
  }

  int ans = 0;

  for (int i = 0; i < n - 1; i++) {

    int flg1 = 0;

    for (int j = 0; j < (int)d[i + 1].size(); j++) {
      if (check(0, i + 1, d[i + 1][j], rh) == true)
        flg1 = 1;
    }

    int flg2 = 0;

    for (int j = 0; j < (int)d[n - i - 1].size(); j++) {
      if (check(i + 1, n, d[n - i - 1][j], rh) == true)
        flg2 = 1;
    }

    if (flg1 == 0 && flg2 == 0)
      ans++;
  }

  cout << 2 << endl;
  cout << ans << endl;

  return 0;
}