Problem p02962 (C++)

Buggy submission (status: Runtime Error):
// Head File
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;

#define il inline

// Variable
#define ll long long
#define ull unsigned long long
#define db double
#define lb long double
#define ui unsigned int

// Debug
#define B cerr << "Break Point" << endl;
#define P(x) cerr << #x << ' ' << "=" << ' ' << (x) << endl;
#define p(x) cerr << #x << ' ' << "=" << ' ' << (x) << ' ';
#define ml(x)                                                                  \
  cerr << "Size of array is " << x * 4 / 1024 / 1024 << " MB" << endl;

// Vector
#define vc vector
#define puf push_front
#define pof pop_front
#define pub push_back
#define pob pop_back
#define vbe(x) x.begin(), x.end()

// Memset
#define ms(x) memset(x, 0, sizeof(x))
#define MS(x) memset(x, 0x3f3f3f3f, sizeof(x))

// Pair
#define fi first
#define se second

// File

#define fin(x) freopen(x, "r", stdin)
#define fou(x) freopen(x, "w", stdout)
void fio() {
#ifndef ONLINE_JUDGE
  freopen("sample.in", "r", stdin);
  freopen("sample.out", "w", stdout);
#endif
}
void pti() {
  double timeuse = clock() * 1000.0 / CLOCKS_PER_SEC;
  cerr << "Timeuse " << timeuse << "ms" << endl;
}
void end() {
#ifndef ONLINE_JUDGE
  pti();
#endif
  exit(0);
}

// Inf
#define INF 0x3f3f3f3f
#define LINF ((long long)(0x3f3f3f3f3f3f3f3f))

// IO
#define pc(s) putchar(s)
#define say(s) cout << s << endl
namespace io {
const int SIZ = 55;
int que[SIZ], op, qr;
char ch;
template <class I> il void gi(I &w) {
  ch = getchar(), op = 1, w = 0;
  while (!isdigit(ch)) {
    if (ch == '-')
      op = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    w = w * 10 + ch - '0';
    ch = getchar();
  }
  w *= op;
}
template <typename T, typename... Args> il void gi(T &t, Args &...args) {
  gi(t);
  gi(args...);
}
template <class I> il void print(I w) {
  qr = 0;
  if (!w)
    putchar('0');
  if (w < 0)
    putchar('-'), w = -w;
  while (w)
    que[++qr] = w % 10 + '0', w /= 10;
  while (qr)
    putchar(que[qr--]);
}
} // namespace io
using io::gi;
using io::print;

const int N = 2e7 + 5;
const int base = 131;
const ll mod = 192608179;

string a, b;
int tag[N];
ll ha[N], hb[N], fac[N];

ll gethash(int x) {
  if (x + b.size() > a.size())
    return -1;
  return (ha[x + b.size() - 1] - ha[x - 1] * fac[b.size()] % mod + mod) % mod;
}
int main() {
  fio();
  cin >> a >> b;
  while (a.size() < b.size() * 2)
    a = a + a;
  a = a + a, a = a + a, a = a + a;
  fac[0] = 1, ha[0] = a[0] - 'a', hb[0] = b[0] - 'a';
  for (int i = 1; i < a.size(); ++i)
    fac[i] = fac[i - 1] * base % mod;
  for (int i = 1; i < a.size(); ++i)
    ha[i] = (ha[i - 1] * base % mod + a[i] - 'a') % mod;
  for (int i = 1; i < b.size(); ++i)
    hb[i] = (hb[i - 1] * base % mod + b[i] - 'a') % mod;
  for (int i = 0; i < a.size(); ++i)
    tag[i] = hb[b.size() - 1] == gethash(i);
  int ans = 0;
  for (int i = a.size() - b.size(); i >= 0; --i)
    if (tag[i])
      tag[i] += tag[i + b.size()], ans = max(ans, tag[i]);
  if (ans + 1 >= a.size() / b.size())
    print(-1);
  else
    print(ans);
  end();
}


Fixed submission:
// Head File
#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <map>
#include <set>
#include <vector>
using namespace std;

#define il inline

// Variable
#define ll long long
#define ull unsigned long long
#define db double
#define lb long double
#define ui unsigned int

// Debug
#define B cerr << "Break Point" << endl;
#define P(x) cerr << #x << ' ' << "=" << ' ' << (x) << endl;
#define p(x) cerr << #x << ' ' << "=" << ' ' << (x) << ' ';
#define ml(x)                                                                  \
  cerr << "Size of array is " << x * 4 / 1024 / 1024 << " MB" << endl;

// Vector
#define vc vector
#define puf push_front
#define pof pop_front
#define pub push_back
#define pob pop_back
#define vbe(x) x.begin(), x.end()

// Memset
#define ms(x) memset(x, 0, sizeof(x))
#define MS(x) memset(x, 0x3f3f3f3f, sizeof(x))

// Pair
#define fi first
#define se second

// File

#define fin(x) freopen(x, "r", stdin)
#define fou(x) freopen(x, "w", stdout)
void fio() {
#ifndef ONLINE_JUDGE
  freopen("sample.in", "r", stdin);
  freopen("sample.out", "w", stdout);
#endif
}
void pti() {
  double timeuse = clock() * 1000.0 / CLOCKS_PER_SEC;
  cerr << "Timeuse " << timeuse << "ms" << endl;
}
void end() {
#ifndef ONLINE_JUDGE
  pti();
#endif
  exit(0);
}

// Inf
#define INF 0x3f3f3f3f
#define LINF ((long long)(0x3f3f3f3f3f3f3f3f))

// IO
#define pc(s) putchar(s)
#define say(s) cout << s << endl
namespace io {
const int SIZ = 55;
int que[SIZ], op, qr;
char ch;
template <class I> il void gi(I &w) {
  ch = getchar(), op = 1, w = 0;
  while (!isdigit(ch)) {
    if (ch == '-')
      op = -1;
    ch = getchar();
  }
  while (isdigit(ch)) {
    w = w * 10 + ch - '0';
    ch = getchar();
  }
  w *= op;
}
template <typename T, typename... Args> il void gi(T &t, Args &...args) {
  gi(t);
  gi(args...);
}
template <class I> il void print(I w) {
  qr = 0;
  if (!w)
    putchar('0');
  if (w < 0)
    putchar('-'), w = -w;
  while (w)
    que[++qr] = w % 10 + '0', w /= 10;
  while (qr)
    putchar(que[qr--]);
}
} // namespace io
using io::gi;
using io::print;

const int N = 2e7 + 5;
const int base = 131;
const ll mod = 192608179;

string a, b;
int tag[N];
ll ha[N], hb[N], fac[N];

ll gethash(int x) {
  if (x + b.size() > a.size())
    return -1;
  return (ha[x + b.size() - 1] - ha[x - 1] * fac[b.size()] % mod + mod) % mod;
}
int main() {
  cin >> a >> b;
  while (a.size() < b.size() * 2)
    a = a + a;
  a = a + a, a = a + a, a = a + a;
  fac[0] = 1, ha[0] = a[0] - 'a', hb[0] = b[0] - 'a';
  for (int i = 1; i < a.size(); ++i)
    fac[i] = fac[i - 1] * base % mod;
  for (int i = 1; i < a.size(); ++i)
    ha[i] = (ha[i - 1] * base % mod + a[i] - 'a') % mod;
  for (int i = 1; i < b.size(); ++i)
    hb[i] = (hb[i - 1] * base % mod + b[i] - 'a') % mod;
  for (int i = 0; i < a.size(); ++i)
    tag[i] = hb[b.size() - 1] == gethash(i);
  int ans = 0;
  for (int i = a.size() - b.size(); i >= 0; --i)
    if (tag[i])
      tag[i] += tag[i + b.size()], ans = max(ans, tag[i]);
  if (ans + 1 >= a.size() / b.size())
    print(-1);
  else
    print(ans);
  end();
}