Problem p02962 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <string>
#include <vector>

struct KMP {
  const std::string &pattern;
  std::vector<int> table;

  explicit KMP(const std::string &p) : pattern(p), table(p.size() + 1) {
    table[0] = -1;
    table[1] = 0;

    int i = 2;
    int j = 0;
    while (i < pattern.size()) {
      if (pattern[i - 1] == pattern[j]) {
        table[i] = j + 1;
        i += 1;
        j += 1;
      } else if (j > 0) {
        j = table[j];
      } else {
        table[i] = 0;
        i += 1;
      }
    }
    if (pattern.size() > 1) {
      table[pattern.size()] = j + 1;
    }
  }

  std::vector<int> search(const std::string &text) {
    std::vector<int> matches;
    int m = 0;
    int i = 0;
    while (m + i < text.size()) {
      if (i < pattern.size() && pattern[i] == text[m + i]) {
        i += 1;
      } else {
        if (i == pattern.size()) {
          matches.push_back(m);
        }
        m = m + i - table[i];
        if (i > 0) {
          i = table[i];
        }
      }
    }
    return matches;
  }
};

// verify: https://atcoder.jp/contests/abc135/tasks/abc135_f

#include <iostream>
#include <map>

using namespace std;

const int INF = 1e9;

map<int, int> nexts;
vector<bool> vis;
pair<int, int> trace(int pos, int init) {
  if (pos == init) {
    return make_pair(pos, INF);
  } else if (nexts.count(pos) == 0) {
    return make_pair(pos, 1);
  } else {
    auto recur = trace(nexts[pos], init);
    return make_pair(recur.first, recur.second + 1);
  }
}

int main() {
  string s, t;
  cin >> s >> t;

  string u;
  while (u.size() < s.size() + t.size()) {
    u.insert(u.end(), s.begin(), s.end());
  }

  KMP kmp(t);
  auto matches = kmp.search(u);
  for (const auto &fr : matches) {
    nexts[fr] = (fr + t.size()) % s.size();
  }
  vis = vector<bool>(s.size(), false);

  int ans = 0;
  for (int fr = 0; fr < s.size(); ++fr) {
    if (nexts.count(fr) == 0) {
      continue;
    }
    if (vis[fr]) {
      continue;
    }
    ans = max(ans, trace(nexts[fr], fr).second);
  }

  cout << ((ans >= INF) ? -1 : ans) << endl;
  return 0;
}


Fixed submission:
#include <string>
#include <vector>

struct KMP {
  const std::string &pattern;
  std::vector<int> table;

  explicit KMP(const std::string &p) : pattern(p), table(p.size() + 1) {
    table[0] = -1;
    table[1] = 0;

    int i = 2;
    int j = 0;
    while (i < pattern.size()) {
      if (pattern[i - 1] == pattern[j]) {
        table[i] = j + 1;
        i += 1;
        j += 1;
      } else if (j > 0) {
        j = table[j];
      } else {
        table[i] = 0;
        i += 1;
      }
    }
    if (pattern.size() > 1) {
      table[pattern.size()] = j + 1;
    }
  }

  std::vector<int> search(const std::string &text) {
    std::vector<int> matches;
    int m = 0;
    int i = 0;
    while (m + i < text.size()) {
      if (i < pattern.size() && pattern[i] == text[m + i]) {
        i += 1;
      } else {
        if (i == pattern.size()) {
          matches.push_back(m);
        }
        m = m + i - table[i];
        if (i > 0) {
          i = table[i];
        }
      }
    }
    return matches;
  }
};

// verify: https://atcoder.jp/contests/abc135/tasks/abc135_f

#include <iostream>
#include <map>

using namespace std;

const int INF = 1e9;

map<int, int> nexts;
vector<bool> vis;
pair<int, int> trace(int pos, int init) {
  vis[pos] = true;
  if (pos == init) {
    return make_pair(pos, INF);
  } else if (nexts.count(pos) == 0) {
    return make_pair(pos, 1);
  } else {
    auto recur = trace(nexts[pos], init);
    return make_pair(recur.first, recur.second + 1);
  }
}

int main() {
  string s, t;
  cin >> s >> t;

  string u;
  while (u.size() < s.size() + t.size()) {
    u.insert(u.end(), s.begin(), s.end());
  }

  KMP kmp(t);
  auto matches = kmp.search(u);
  for (const auto &fr : matches) {
    nexts[fr] = (fr + t.size()) % s.size();
  }
  vis = vector<bool>(s.size(), false);

  int ans = 0;
  for (int fr = 0; fr < s.size(); ++fr) {
    if (nexts.count(fr) == 0) {
      continue;
    }
    if (vis[fr]) {
      continue;
    }
    ans = max(ans, trace(nexts[fr], fr).second);
  }

  cout << ((ans >= INF) ? -1 : ans) << endl;
  return 0;
}