Problem p02962 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

#define int long long
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
typedef pair<int, int> pii;
const int INF = 1l << 60;
#define u_b upper_bound
#define l_b lower_bound

const int mod = 1000000007;

template <int M = 1000000007> struct ModInt {
  int data;

  ModInt(int data) : data(data) {}

  ModInt() : data(0) {}

  inline ModInt<M> operator+(ModInt<M> const &right) const {
    int temp = data + right.data;
    return ModInt(temp > M ? temp - M : temp);
  }

  inline ModInt<M> operator-(ModInt<M> const &right) const {
    int temp = data - right.data;
    return ModInt(temp < 0 ? temp + M : temp);
  }

  inline ModInt<M> operator*(ModInt<M> const &right) const {
    int temp = data * right.data % M;
    return ModInt(temp < 0 ? temp + M : temp);
  }

  inline bool operator==(ModInt<M> const &right) const {
    return data == right.data;
  }

  inline bool operator!=(ModInt<M> const &right) const {
    return data != right.data;
  }
};

vector<ModInt<>> createHash(string s);

int solve(int begin); // sのbegin文字目から始めた時の答え

void preCalc();

string S, T;
vector<ModInt<>> shash, thash;
bool inf;             // 無限?
bool calling[500500]; // 再帰関数solveでループになっているか確認

signed main() {
  preCalc();
  cin >> S >> T;
  shash = createHash(S);
  thash = createHash(T);
  int ans = 0;
  rep(i, S.length()) {
    ans = max(ans, solve(i));
    if (inf) {
      cout << -1 << endl;
      return 0;
    }
  }
  cout << ans << endl;
  return 0;
}

ModInt<> powMemo[500500];
int memo[500500];

void preCalc() {
  memo[0] = -1;
  powMemo[0] = 1;
  for (int i = 1; i < 500500; ++i) {
    memo[i] = -1;
    powMemo[i] = powMemo[i - 1] * 27;
  }
}

ModInt<> Slice(vector<ModInt<>> hash, int begin, int length) {
  return hash[begin + length] - hash[begin] * powMemo[length];
}

int solve(int begin) {
  if (calling[begin]) {
    inf = true;
    return memo[begin] = 0;
  }
  calling[begin] = true;
  int tPlace = 0;
  int sPlace = begin;
  int remainLength = T.length();
  while (remainLength) {
    int nextLength =
        min(remainLength, (int)min(T.length() - tPlace, S.length() - sPlace));
    if (Slice(shash, sPlace, nextLength) != Slice(thash, tPlace, nextLength)) {
      calling[begin] = false;
      return memo[begin] = 0;
    }
    remainLength -= nextLength;
    sPlace += nextLength;
    tPlace += nextLength;
    if (sPlace == S.length())
      sPlace = 0;
    if (tPlace == T.length())
      tPlace = 0;
  }
  int res = (memo[sPlace] != -1 ? memo[sPlace] : solve(sPlace)) + 1;
  calling[begin] = false;
  return memo[begin] = res;
}

vector<ModInt<>> createHash(string s) {
  vector<ModInt<>> hash(s.length() + 1);
  rep(i, s.length()) { hash[i + 1] = hash[i] * 27 + (s[i] - 96); }
  return hash;
}


Fixed submission:
#include <bits/stdc++.h>

#define int long long
using namespace std;
#define rep(i, n) for (int i = 0; i < (n); ++i)
typedef pair<int, int> pii;
const int INF = 1l << 60;
#define u_b upper_bound
#define l_b lower_bound

const int mod = 1000000007;

template <int M = 1000000007> struct ModInt {
  int data;

  ModInt(int data) : data(data) {}

  ModInt() : data(0) {}

  inline ModInt<M> operator+(ModInt<M> const &right) const {
    int temp = data + right.data;
    return ModInt(temp > M ? temp - M : temp);
  }

  inline ModInt<M> operator-(ModInt<M> const &right) const {
    int temp = data - right.data;
    return ModInt(temp < 0 ? temp + M : temp);
  }

  inline ModInt<M> operator*(ModInt<M> const &right) const {
    int temp = data * right.data % M;
    return ModInt(temp < 0 ? temp + M : temp);
  }

  inline bool operator==(ModInt<M> const &right) const {
    return data == right.data;
  }

  inline bool operator!=(ModInt<M> const &right) const {
    return data != right.data;
  }
};

vector<ModInt<>> createHash(string s);

int solve(int begin); // sのbegin文字目から始めた時の答え

void preCalc();

string S, T;
vector<ModInt<>> shash, thash;
bool inf;             // 無限?
bool calling[500500]; // 再帰関数solveでループになっているか確認

signed main() {
  preCalc();
  cin >> S >> T;
  shash = createHash(S);
  thash = createHash(T);
  int ans = 0;
  rep(i, S.length()) {
    ans = max(ans, solve(i));
    if (inf) {
      cout << -1 << endl;
      return 0;
    }
  }
  cout << ans << endl;
  return 0;
}

ModInt<> powMemo[500500];
int memo[500500];

void preCalc() {
  memo[0] = -1;
  powMemo[0] = 1;
  for (int i = 1; i < 500500; ++i) {
    memo[i] = -1;
    powMemo[i] = powMemo[i - 1] * 27;
  }
}

ModInt<> Slice(vector<ModInt<>> const &hash, int begin, int length) {
  return hash[begin + length] - hash[begin] * powMemo[length];
}

int solve(int begin) {
  if (calling[begin]) {
    inf = true;
    return memo[begin] = 0;
  }
  calling[begin] = true;
  int tPlace = 0;
  int sPlace = begin;
  int remainLength = T.length();
  while (remainLength) {
    int nextLength =
        min(remainLength, (int)min(T.length() - tPlace, S.length() - sPlace));
    if (Slice(shash, sPlace, nextLength) != Slice(thash, tPlace, nextLength)) {
      calling[begin] = false;
      return memo[begin] = 0;
    }
    remainLength -= nextLength;
    sPlace += nextLength;
    tPlace += nextLength;
    if (sPlace == S.length())
      sPlace = 0;
    if (tPlace == T.length())
      tPlace = 0;
  }
  int res = (memo[sPlace] != -1 ? memo[sPlace] : solve(sPlace)) + 1;
  calling[begin] = false;
  return memo[begin] = res;
}

vector<ModInt<>> createHash(string s) {
  vector<ModInt<>> hash(s.length() + 1);
  rep(i, s.length()) { hash[i + 1] = hash[i] * 27 + (s[i] - 96); }
  return hash;
}