Problem p02962 (C++)

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

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, n, m) for (int i = (int)(n); i <= (int)(m); i++)
#define RFOR(i, n, m) for (int i = (int)(n); i >= (int)(m); i--)
#define ITR(x, c) for (__typeof(c.begin()) x = c.begin(); x != c.end(); x++)
#define RITR(x, c) for (__typeof(c.rbegin()) x = c.rbegin(); x != c.rend(); x++)
#define setp(n) fixed << setprecision(n)

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

#define ll long long
#define vll vector<ll>
#define vi vector<int>
#define pll pair<ll, ll>
#define pi pair<int, int>

#define all(a) (a.begin()), (a.end())
#define rall(a) (a.rbegin()), (a.rend())
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ins insert

using namespace std;

struct SuffixArray {
  vector<int> SA;
  const string s;

  SuffixArray(const string &str) : s(str) {
    SA.resize(s.size());
    iota(begin(SA), end(SA), 0);
    sort(begin(SA), end(SA),
         [&](int a, int b) { return s[a] == s[b] ? a > b : s[a] < s[b]; });
    vector<int> classes(s.size()), c(s.begin(), s.end()), cnt(s.size());
    for (int len = 1; len < s.size(); len <<= 1) {
      for (int i = 0; i < s.size(); i++) {
        if (i > 0 && c[SA[i - 1]] == c[SA[i]] && SA[i - 1] + len < s.size() &&
            c[SA[i - 1] + len / 2] == c[SA[i] + len / 2]) {
          classes[SA[i]] = classes[SA[i - 1]];
        } else {
          classes[SA[i]] = i;
        }
      }
      iota(begin(cnt), end(cnt), 0);
      copy(begin(SA), end(SA), begin(c));
      for (int i = 0; i < s.size(); i++) {
        int s1 = c[i] - len;
        if (s1 >= 0)
          SA[cnt[classes[s1]]++] = s1;
      }
      classes.swap(c);
    }
  }

  int operator[](int k) const { return SA[k]; }

  size_t size() const { return s.size(); }

  bool lt_substr(const string &t, int si = 0, int ti = 0) {
    int sn = (int)s.size(), tn = (int)t.size();
    while (si < sn && ti < tn) {
      if (s[si] < t[ti])
        return true;
      if (s[si] > t[ti])
        return false;
      ++si, ++ti;
    }
    return si >= sn && ti < tn;
  }

  int lower_bound(const string &t) {
    int low = -1, high = (int)SA.size();
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (lt_substr(t, SA[mid]))
        low = mid;
      else
        high = mid;
    }
    return high;
  }

  pair<int, int> lower_upper_bound(string &t) {
    int idx = lower_bound(t);
    int low = idx - 1, high = (int)SA.size();
    t.back()++;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (lt_substr(t, SA[mid]))
        low = mid;
      else
        high = mid;
    }
    t.back()--;
    return {idx, high};
  }

  void output() {
    for (int i = 0; i < size(); i++) {
      cout << i << ": " << s.substr(SA[i]) << endl;
    }
  }
};

vector<vi> adj;
vector<bool> visited;
vi dist;
bool loop = false;

int dfs(int v) {
  if (loop)
    return -1;
  visited[v] = true;
  if (adj[v].empty()) {
    return dist[v] = 0;
    ;
  }
  int u = adj[v][0];
  if (visited[u] && dist[u] == -1) {
    loop = true;
    return -1;
  }
  return dist[v] = dfs(u) + 1;
}

//-------------------------------------------------

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  string s, t;
  cin >> s >> t;
  int n = s.size();
  int m = t.size();
  int l = 0;
  string u;
  rep(i, n + m - 1) { u.pb(s[i % n]); }
  SuffixArray sa(u);
  auto r = sa.lower_upper_bound(t);
  adj.resize(n);
  visited.resize(n);
  dist.resize(n, -1);
  FOR(i, r.fi, r.se - 1) {
    int from = sa[i];
    int to = (sa[i] + m) % n;
    adj[from].pb(to);
  }
  int ans = 0;
  rep(i, n) {
    chmax(ans, dfs(i));
    if (loop)
      break;
  }
  if (loop) {
    cout << "-1\n";
  } else {
    cout << ans << "\n";
  }
  return 0;
}


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

#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define FOR(i, n, m) for (int i = (int)(n); i <= (int)(m); i++)
#define RFOR(i, n, m) for (int i = (int)(n); i >= (int)(m); i--)
#define ITR(x, c) for (__typeof(c.begin()) x = c.begin(); x != c.end(); x++)
#define RITR(x, c) for (__typeof(c.rbegin()) x = c.rbegin(); x != c.rend(); x++)
#define setp(n) fixed << setprecision(n)

template <class T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

#define ll long long
#define vll vector<ll>
#define vi vector<int>
#define pll pair<ll, ll>
#define pi pair<int, int>

#define all(a) (a.begin()), (a.end())
#define rall(a) (a.rbegin()), (a.rend())
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ins insert

using namespace std;

struct SuffixArray {
  vector<int> SA;
  const string s;

  SuffixArray(const string &str) : s(str) {
    SA.resize(s.size());
    iota(begin(SA), end(SA), 0);
    sort(begin(SA), end(SA),
         [&](int a, int b) { return s[a] == s[b] ? a > b : s[a] < s[b]; });
    vector<int> classes(s.size()), c(s.begin(), s.end()), cnt(s.size());
    for (int len = 1; len < s.size(); len <<= 1) {
      for (int i = 0; i < s.size(); i++) {
        if (i > 0 && c[SA[i - 1]] == c[SA[i]] && SA[i - 1] + len < s.size() &&
            c[SA[i - 1] + len / 2] == c[SA[i] + len / 2]) {
          classes[SA[i]] = classes[SA[i - 1]];
        } else {
          classes[SA[i]] = i;
        }
      }
      iota(begin(cnt), end(cnt), 0);
      copy(begin(SA), end(SA), begin(c));
      for (int i = 0; i < s.size(); i++) {
        int s1 = c[i] - len;
        if (s1 >= 0)
          SA[cnt[classes[s1]]++] = s1;
      }
      classes.swap(c);
    }
  }

  int operator[](int k) const { return SA[k]; }

  size_t size() const { return s.size(); }

  bool lt_substr(const string &t, int si = 0, int ti = 0) {
    int sn = (int)s.size(), tn = (int)t.size();
    while (si < sn && ti < tn) {
      if (s[si] < t[ti])
        return true;
      if (s[si] > t[ti])
        return false;
      ++si, ++ti;
    }
    return si >= sn && ti < tn;
  }

  int lower_bound(const string &t) {
    int low = -1, high = (int)SA.size();
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (lt_substr(t, SA[mid]))
        low = mid;
      else
        high = mid;
    }
    return high;
  }

  pair<int, int> lower_upper_bound(string &t) {
    int idx = lower_bound(t);
    int low = idx - 1, high = (int)SA.size();
    t.back()++;
    while (high - low > 1) {
      int mid = (low + high) / 2;
      if (lt_substr(t, SA[mid]))
        low = mid;
      else
        high = mid;
    }
    t.back()--;
    return {idx, high};
  }

  void output() {
    for (int i = 0; i < size(); i++) {
      cout << i << ": " << s.substr(SA[i]) << endl;
    }
  }
};

vector<vi> adj;
vector<bool> visited;
vi dist;
bool loop = false;

int dfs(int v) {
  if (loop)
    return -1;
  visited[v] = true;
  if (adj[v].empty()) {
    return dist[v] = 0;
    ;
  }
  int u = adj[v][0];
  if (visited[u] && dist[u] == -1) {
    loop = true;
    return -1;
  }
  return dist[v] = dfs(u) + 1;
}

//-------------------------------------------------

int main(void) {
  cin.tie(0);
  ios::sync_with_stdio(false);
  string s, t;
  cin >> s >> t;
  int n = s.size();
  int m = t.size();
  int l = 0;
  string u;
  rep(i, n + m - 1) { u.pb(s[i % n]); }
  SuffixArray sa(u);
  auto r = sa.lower_upper_bound(t);
  adj.resize(n);
  visited.resize(n);
  dist.resize(n, -1);
  FOR(i, r.fi, r.se - 1) {
    int from = sa[i];
    int to = (sa[i] + m) % n;
    adj[from].pb(to);
  }
  int ans = 0;
  rep(i, n) {
    if (dist[i] != -1)
      continue;
    chmax(ans, dfs(i));
    if (loop)
      break;
  }
  if (loop) {
    cout << "-1\n";
  } else {
    cout << ans << "\n";
  }
  return 0;
}