Problem p02962 (C++)

Buggy submission (status: Runtime Error):
#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx2,tune=native")
// #pragma comment(linker, "/stack:200000000")

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;

#define X first
#define Y second

// #include <boost/unordered_map.hpp>
// using namespace boost;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
tree_order_statistics_node_update> rbtree; rbtree T;
*/

using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;
// using i128 = __int128_t;
// using u128 = __uint128_t;
using i128 = i64;
using u128 = u64;

ll power(ll a, ll b, ll p) {
  if (!b)
    return 1;
  ll t = power(a, b / 2, p);
  t = t * t % p;
  if (b & 1)
    t = t * a % p;
  return t;
}

ll exgcd(ll a, ll b, ll &x, ll &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  ll px, py;
  ll d = exgcd(b, a % b, px, py);
  x = py;
  y = px - a / b * py;
  return d;
}

template <class T> inline void freshmin(T &a, const T &b) {
  if (a > b)
    a = b;
}

template <class T> inline void freshmax(T &a, const T &b) {
  if (a < b)
    a = b;
}

// #define getchar getchar_unlocked
// #define putchar putchar_unlocked

int inp() {
  int x = 0, f = 0;
  char ch;
  for (ch = getchar(); !isdigit(ch); ch = getchar())
    if (ch == '-')
      f = 1;
  for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  return f ? -x : x;
}

ll inp_ll() {
  ll x = 0;
  int f = 0;
  char ch;
  for (ch = getchar(); !isdigit(ch); ch = getchar())
    if (ch == '-')
      f = 1;
  for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  return f ? -x : x;
}

template <class T> bool read(T &x) {
  x = 0;
  char ch = getchar();
  if (ch == EOF)
    return 0;
  for (; !isdigit(ch);) {
    ch = getchar();
    if (ch == EOF)
      return 0;
  }
  for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  return 1;
}

template <class T> void write(T x) {
  static char s[22];
  static char *it = s + 20;
  static char *end = s + 20;
  if (!x)
    *--it = '0';
  while (x) {
    *--it = x % 10 + '0';
    x /= 10;
  }
  for (; it < end; ++it)
    putchar(*it);
}

template <class T> void writeln(T x) {
  write(x);
  putchar('\n');
}

const int MAXN = 5000010;
const int INF = 1000000000;
const int MOD = 1000000007;

int pre[MAXN];

void kmp(char *s, int n) {
  for (int i = 2; i <= n; ++i) {
    int j = pre[i - 1];
    while (j && s[j + 1] != s[i])
      j = pre[j];
    pre[i] = s[j + 1] == s[i] ? j + 1 : 0;
  }
}

int n, m;
char s[MAXN], t[MAXN];

bool u[MAXN], in[MAXN];
int to[MAXN], F[MAXN];

int head, tail, Q[MAXN];

int main() {

  scanf("%s", s + 1);
  scanf("%s", t + 1);
  n = strlen(s + 1);
  m = strlen(t + 1);

  int multi = m / n + 1;

  if ((multi + 1) * n > 4000000) {
    puts("caonima");
    return 0;
  }

  for (int k = 1; k <= multi; ++k)
    for (int i = 1; i <= n; ++i) {
      if (k * n + i > 4000000) {
        puts("caonima");
        return 0;
      }
      s[k * n + i] = s[i];
    }

  int N = (multi + 1) * n;

  kmp(t, m);

  int cur = 0;
  int flag = 0;
  for (int i = 1; i <= N; ++i) {
    while (cur && s[i] != t[cur + 1])
      cur = pre[cur];
    if (s[i] == t[cur + 1])
      cur++;
    if (cur == m) {
      flag = 1;
      int x = (i - m + 1) % n, y = (i + 1) % n;
      if (x == 0)
        x = n;
      if (y == 0)
        y = n;
      to[x] = y;
      cur = pre[cur];
    }
  }

  if (!flag) {
    puts("0");
    return 0;
  }

  for (int i = 1; i <= n; ++i)
    if (!u[i]) {
      head = tail = 1;
      Q[1] = i;
      in[i] = 1;
      u[i] = 1;
      while (1) {
        int x = Q[tail];
        int y = to[x];
        if (!y)
          break;
        if (u[y]) {
          if (in[y]) {
            puts("-1");
            return 0;
          }
          break;
        }
        Q[++tail] = y;
        in[y] = 1;
        u[y] = 1;
      }
      for (int j = tail; j >= 1; --j) {
        F[Q[j]] = F[to[Q[j]]] + 1;
        in[Q[j]] = 0;
      }
    }

  int ans = 0;
  for (int i = 1; i <= n; ++i)
    freshmax(ans, F[i]);
  cout << ans - 1 << endl;

  return 0;
}


Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<ld, ld> pdd;

#define X first
#define Y second

// #include <boost/unordered_map.hpp>
// using namespace boost;

/*
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag,
tree_order_statistics_node_update> rbtree; rbtree T;
*/

using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;
// using i128 = __int128_t;
// using u128 = __uint128_t;
using i128 = i64;
using u128 = u64;

ll power(ll a, ll b, ll p) {
  if (!b)
    return 1;
  ll t = power(a, b / 2, p);
  t = t * t % p;
  if (b & 1)
    t = t * a % p;
  return t;
}

ll exgcd(ll a, ll b, ll &x, ll &y) {
  if (b == 0) {
    x = 1;
    y = 0;
    return a;
  }
  ll px, py;
  ll d = exgcd(b, a % b, px, py);
  x = py;
  y = px - a / b * py;
  return d;
}

template <class T> inline void freshmin(T &a, const T &b) {
  if (a > b)
    a = b;
}

template <class T> inline void freshmax(T &a, const T &b) {
  if (a < b)
    a = b;
}

// #define getchar getchar_unlocked
// #define putchar putchar_unlocked

int inp() {
  int x = 0, f = 0;
  char ch;
  for (ch = getchar(); !isdigit(ch); ch = getchar())
    if (ch == '-')
      f = 1;
  for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  return f ? -x : x;
}

ll inp_ll() {
  ll x = 0;
  int f = 0;
  char ch;
  for (ch = getchar(); !isdigit(ch); ch = getchar())
    if (ch == '-')
      f = 1;
  for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  return f ? -x : x;
}

template <class T> bool read(T &x) {
  x = 0;
  char ch = getchar();
  if (ch == EOF)
    return 0;
  for (; !isdigit(ch);) {
    ch = getchar();
    if (ch == EOF)
      return 0;
  }
  for (; isdigit(ch); x = x * 10 + ch - '0', ch = getchar())
    ;
  return 1;
}

template <class T> void write(T x) {
  static char s[22];
  static char *it = s + 20;
  static char *end = s + 20;
  if (!x)
    *--it = '0';
  while (x) {
    *--it = x % 10 + '0';
    x /= 10;
  }
  for (; it < end; ++it)
    putchar(*it);
}

template <class T> void writeln(T x) {
  write(x);
  putchar('\n');
}

const int MAXN = 5000010;
const int INF = 1000000000;
const int MOD = 1000000007;

int pre[MAXN];

void kmp(char *s, int n) {
  for (int i = 2; i <= n; ++i) {
    int j = pre[i - 1];
    while (j && s[j + 1] != s[i])
      j = pre[j];
    pre[i] = s[j + 1] == s[i] ? j + 1 : 0;
  }
}

int n, m;
char s[MAXN], t[MAXN];

bool u[MAXN], in[MAXN];
int to[MAXN], F[MAXN];

int head, tail, Q[MAXN];

int main() {

  scanf("%s", s + 1);
  scanf("%s", t + 1);
  n = strlen(s + 1);
  m = strlen(t + 1);

  int multi = m / n + 1;

  if ((multi + 1) * n > 4000000) {
    puts("caonima");
    return 0;
  }

  for (int k = 1; k <= multi; ++k)
    for (int i = 1; i <= n; ++i) {
      if (k * n + i > 4000000) {
        puts("caonima");
        return 0;
      }
      s[k * n + i] = s[i];
    }

  int N = (multi + 1) * n;

  kmp(t, m);

  int cur = 0;
  int flag = 0;
  for (int i = 1; i <= N; ++i) {
    while (cur && s[i] != t[cur + 1])
      cur = pre[cur];
    if (s[i] == t[cur + 1])
      cur++;
    if (cur == m) {
      flag = 1;
      int x = (i - m + 1) % n, y = (i + 1) % n;
      if (x == 0)
        x = n;
      if (y == 0)
        y = n;
      to[x] = y;
      cur = pre[cur];
    }
  }

  if (!flag) {
    puts("0");
    return 0;
  }

  for (int i = 1; i <= n; ++i)
    if (!u[i]) {
      head = tail = 1;
      Q[1] = i;
      in[i] = 1;
      u[i] = 1;
      while (1) {
        int x = Q[tail];
        int y = to[x];
        if (!y)
          break;
        if (u[y]) {
          if (in[y]) {
            puts("-1");
            return 0;
          }
          break;
        }
        Q[++tail] = y;
        in[y] = 1;
        u[y] = 1;
      }
      for (int j = tail; j >= 1; --j) {
        F[Q[j]] = F[to[Q[j]]] + 1;
        in[Q[j]] = 0;
      }
    }

  int ans = 0;
  for (int i = 1; i <= n; ++i)
    freshmax(ans, F[i]);
  cout << ans - 1 << endl;

  return 0;
}