Problem p02962 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
// const ll mod = 1000000007;
template <class Z> Z rng(Z a, Z b) {
  static mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
  return uniform_int_distribution<Z>(a, b - 1)(mt);
}

struct RollingHash {
  static constexpr uint64_t P0 = 4e9 + 7;
  static constexpr uint64_t P1 = 4e9 + 9;
  static uint64_t B0;
  static uint64_t B1;
  static vector<uint64_t> powB0;
  static vector<uint64_t> powB1;
  const int n;
  vector<uint64_t> h0;
  vector<uint64_t> h1;
  template <class Itr>
  RollingHash(Itr first, Itr last)
      : n(distance(first, last)), h0(n + 1), h1(n + 1) {
    for (int i = 0; i < n; ++i, ++first) {
      h0[i + 1] = (h0[i] * B0 + *first) % P0;
      h1[i + 1] = (h1[i] * B1 + *first) % P1;
    }
    while (powB0.size() <= n) {
      powB0.push_back(powB0.back() * B0 % P0);
      powB1.push_back(powB1.back() * B1 % P1);
    }
  }
  uint64_t get0(int l, int r) {
    return (h0[r] + (P0 - h0[l]) * powB0[r - l]) % P0;
  }
  uint64_t get1(int l, int r) {
    return (h1[r] + (P1 - h1[l]) * powB1[r - l]) % P1;
  }
  pair<uint64_t, uint64_t> get(int l, int r) {
    return {get0(l, r), get1(l, r)};
  }
  bool eq(int l0, int r0, int l1, int r1) {
    return get0(l0, r0) == get0(l1, r1) and get1(l0, r0) == get1(l1, r1);
  }
  template <class Itr> static uint64_t get0(Itr first, Itr last) {
    uint64_t res = 0;
    while (first != last) {
      res = (res * B0 + *first++) % P0;
    }
    return res;
  }
  template <class Itr> static uint64_t get1(Itr first, Itr last) {
    uint64_t res = 0;
    while (first != last) {
      res = (res * B1 + *first++) % P1;
    }
    return res;
  }
};
uint64_t RollingHash::B0 = rng<unsigned>(1, RollingHash::P0);
uint64_t RollingHash::B1 = rng<unsigned>(1, RollingHash::P1);
vector<uint64_t> RollingHash::powB0{1};
vector<uint64_t> RollingHash::powB1{1};
string t, s;

ll dp[2][505000];

int main() {
  // cout.precision(10);
  cin >> s >> t;
  RollingHash shash(s.begin(), s.end()), thash(t.begin(), t.end());
  for (int i = 0; i <= 5e5; i++) {
    dp[0][i] = dp[1][i] = INF;
  }
  queue<i_i> que;
  for (int i = 0; i < s.size(); i++) {
    ll len = s.size() - i;
    chmin(len, (ll)t.size());
    if (shash.get(i, i + len) != thash.get(0, len)) {
      dp[0][i] = 0;
      que.push({0, i});
    }
  }
  for (int i = 0; i < t.size(); i++) {
    ll len = t.size() - i;
    chmin(len, (ll)s.size());
    if (thash.get(i, i + len) != shash.get(0, len)) {
      dp[1][i] = -INF;
      que.push({1, i});
    }
  }
  while (!que.empty()) {
    i_i now = que.front();
    cerr << now.first << " " << now.second << " " << dp[now.first][now.second]
         << endl;
    que.pop();
    if (now.first == 0) {
      if (now.second >= t.size()) {
        if (chmin(dp[0][now.second - t.size()], dp[0][now.second] + 1)) {
          que.push({0, now.second - t.size()});
        }
        continue;
      } else {
        if (chmin(dp[1][t.size() - now.second], dp[0][now.second])) {
          que.push({1, t.size() - now.second});
        }
      }
    }
    if (now.first == 1) {
      if (now.second > s.size()) {
        if (chmin(dp[1][now.second - s.size()], dp[1][now.second])) {
          que.push({1, now.second - s.size()});
        }
        continue;
      } else {
        if (chmin(dp[0][s.size() - now.second], dp[1][now.second] + 1)) {
          chmax(dp[0][s.size() - now.second], (ll)0);
          que.push({0, s.size() - now.second});
        }
      }
    }
  }
  ll ans = 0;
  for (int i = 0; i < s.size(); i++) {
    chmax(ans, dp[0][i]);
  }
  if (ans == INF)
    ans = -1;
  cout << ans << endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;
template <class T> inline bool chmax(T &a, T b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <class T> inline bool chmin(T &a, T b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
// const ll mod = 1000000007;
template <class Z> Z rng(Z a, Z b) {
  static mt19937 mt(chrono::steady_clock::now().time_since_epoch().count());
  return uniform_int_distribution<Z>(a, b - 1)(mt);
}

struct RollingHash {
  static constexpr uint64_t P0 = 4e9 + 7;
  static constexpr uint64_t P1 = 4e9 + 9;
  static uint64_t B0;
  static uint64_t B1;
  static vector<uint64_t> powB0;
  static vector<uint64_t> powB1;
  const int n;
  vector<uint64_t> h0;
  vector<uint64_t> h1;
  template <class Itr>
  RollingHash(Itr first, Itr last)
      : n(distance(first, last)), h0(n + 1), h1(n + 1) {
    for (int i = 0; i < n; ++i, ++first) {
      h0[i + 1] = (h0[i] * B0 + *first) % P0;
      h1[i + 1] = (h1[i] * B1 + *first) % P1;
    }
    while (powB0.size() <= n) {
      powB0.push_back(powB0.back() * B0 % P0);
      powB1.push_back(powB1.back() * B1 % P1);
    }
  }
  uint64_t get0(int l, int r) {
    return (h0[r] + (P0 - h0[l]) * powB0[r - l]) % P0;
  }
  uint64_t get1(int l, int r) {
    return (h1[r] + (P1 - h1[l]) * powB1[r - l]) % P1;
  }
  pair<uint64_t, uint64_t> get(int l, int r) {
    return {get0(l, r), get1(l, r)};
  }
  bool eq(int l0, int r0, int l1, int r1) {
    return get0(l0, r0) == get0(l1, r1) and get1(l0, r0) == get1(l1, r1);
  }
  template <class Itr> static uint64_t get0(Itr first, Itr last) {
    uint64_t res = 0;
    while (first != last) {
      res = (res * B0 + *first++) % P0;
    }
    return res;
  }
  template <class Itr> static uint64_t get1(Itr first, Itr last) {
    uint64_t res = 0;
    while (first != last) {
      res = (res * B1 + *first++) % P1;
    }
    return res;
  }
};
uint64_t RollingHash::B0 = rng<unsigned>(1, RollingHash::P0);
uint64_t RollingHash::B1 = rng<unsigned>(1, RollingHash::P1);
vector<uint64_t> RollingHash::powB0{1};
vector<uint64_t> RollingHash::powB1{1};
string t, s;

ll dp[2][505000];

int main() {
  // cout.precision(10);
  cin >> s >> t;
  RollingHash shash(s.begin(), s.end()), thash(t.begin(), t.end());
  for (int i = 0; i <= 5e5; i++) {
    dp[0][i] = dp[1][i] = INF;
  }
  queue<i_i> que;
  for (int i = 0; i < s.size(); i++) {
    ll len = s.size() - i;
    chmin(len, (ll)t.size());
    if (shash.get(i, i + len) != thash.get(0, len)) {
      dp[0][i] = 0;
      que.push({0, i});
    }
  }
  for (int i = 0; i < t.size(); i++) {
    ll len = t.size() - i;
    chmin(len, (ll)s.size());
    if (thash.get(i, i + len) != shash.get(0, len)) {
      dp[1][i] = -INF;
      que.push({1, i});
    }
  }
  while (!que.empty()) {
    i_i now = que.front();
    // cerr << now.first << " " << now.second << " " <<
    // dp[now.first][now.second] << endl;
    que.pop();
    if (now.first == 0) {
      if (now.second >= t.size()) {
        if (chmin(dp[0][now.second - t.size()], dp[0][now.second] + 1)) {
          que.push({0, now.second - t.size()});
        }
        continue;
      } else {
        if (chmin(dp[1][t.size() - now.second], dp[0][now.second])) {
          que.push({1, t.size() - now.second});
        }
      }
    }
    if (now.first == 1) {
      if (now.second > s.size()) {
        if (chmin(dp[1][now.second - s.size()], dp[1][now.second])) {
          que.push({1, now.second - s.size()});
        }
        continue;
      } else {
        if (chmin(dp[0][s.size() - now.second], dp[1][now.second] + 1)) {
          chmax(dp[0][s.size() - now.second], (ll)0);
          que.push({0, s.size() - now.second});
        }
      }
    }
  }
  ll ans = 0;
  for (int i = 0; i < s.size(); i++) {
    chmax(ans, dp[0][i]);
  }
  if (ans == INF)
    ans = -1;
  cout << ans << endl;
  return 0;
}