Problem p01726 (C++) — buggy submission, verdict: Memory Limit Exceeded

#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
#ifdef DEBUG
#define dump(...)                                                              \\
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \\
        << endl)
#else
#define dump(...)
#endif

#undef MCR
#define MCR Mint const &
template <int M> struct Mint {
  struct zerodiv {};
  struct zeropowzero {};
  int x;
  explicit Mint() : x(0) {}
  explicit Mint(int y) {
    if ((x = y % M + M) >= M)
      x -= M;
  }
  Mint &operator+=(MCR m) {
    if ((x += m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator-=(MCR m) {
    if ((x += M - m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator*=(MCR m) {
    x = 1LL * x * m.x % M;
    return *this;
  }
  Mint &operator/=(MCR m) {
    /* !! default x/0 is undefined !! */
    // if(m.x % M == 0) throw zerodiv();
    x = (1LL * x * m.exp(M - 2).x) % M;
    return *this;
  }
  Mint operator+(MCR m) const { return Mint(*this) += m; }
  Mint operator-(MCR m) const { return Mint(*this) -= m; }
  Mint operator*(MCR m) const { return Mint(*this) *= m; }
  Mint operator/(MCR m) const { return Mint(*this) /= m; }
  bool operator<(MCR m) const { return x < m.x; }
  bool operator==(MCR m) const { return x == m.x; }
  Mint inv() const { return exp(M - 2); }
  Mint exp(long long t) const {
    /* !! default 0^0 = 1 !! */
    // if(x==0 && t==0) throw zeropowzero();
    Mint e = *this, res = Mint(1);
    for (; t; e *= e, t >>= 1)
      if (t & 1)
        res *= e;
    return res;
  }
};
template <int M> ostream &operator<<(ostream &os, Mint<M> m) {
  return os << m.x;
}

typedef Mint<1000000007> mint;
typedef Mint<1000000009> mint2;
mint const ZERO(0);
mint const ONE(1);
mint2 const ZERO2(0);
mint2 const ONE2(1);

typedef pair<mint, mint2> hash_t;

// mint e[300010];
// mint2 e2[300010];

int main() {
  srand(time(0));
  mint const B(rand());
  mint2 const B2(rand());
  // rep(i,300010) e[
  string s, t;
  while (cin >> s >> t) {
    vector<hash_t> ok;
    mint hash = ZERO;
    mint2 hash2 = ZERO2;
    rep(i, t.size()) hash = hash * B + mint(t[i]);
    rep(i, t.size()) hash2 = hash2 * B2 + mint2(t[i]);
    rep(i, t.size()) {
      for (char c = 'a'; c <= 'z'; c++) {
        if (c != t[i]) {
          mint mhash = hash + mint(c - t[i]) * B.exp(t.size() - i - 1);
          mint2 mhash2 = hash2 + mint2(c - t[i]) * B2.exp(t.size() - i - 1);
          ok.eb(mhash, mhash2);
        }
        char C = c ^ 32;
        if (C != t[i]) {
          mint mhash = hash + mint(C - t[i]) * B.exp(t.size() - i - 1);
          mint2 mhash2 = hash2 + mint2(C - t[i]) * B2.exp(t.size() - i - 1);
          ok.eb(mhash, mhash2);
        }
      }
    }

    sort(all(ok));
    ok.erase(unique(all(ok)), ok.end());
    dump(ok.size());

    int ans = 0;
    hash = ZERO;
    hash2 = ZERO2;
    rep(i, t.size()) hash = hash * B + mint(s[i]);
    rep(i, t.size()) hash2 = hash2 * B2 + mint2(s[i]);
    rep(i, s.size() - t.size() + 1) {
      ans += binary_search(all(ok), mp(hash, hash2));
      hash = hash * B + mint(s[i + t.size()]) - mint(s[i]) * B.exp(t.size());
      hash2 =
          hash2 * B2 + mint2(s[i + t.size()]) - mint2(s[i]) * B2.exp(t.size());
    }
    cout << ans << endl;
  }
}

Error: MLE

Fixed submission:

#define _CRT_SECURE_NO_WARNINGS
// #define _GLIBCXX_DEBUG
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef pair<int, int> pii;
#define all(c) (c).begin(), (c).end()
#define loop(i, a, b) for (ll i = a; i < ll(b); i++)
#define rep(i, b) loop(i, 0, b)
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
template <class T> ostream &operator<<(ostream &os, vector<T> const &);
template <int n, class... T>
typename enable_if<(n >= sizeof...(T))>::type _ot(ostream &,
                                                  tuple<T...> const &) {}
template <int n, class... T>
typename enable_if<(n < sizeof...(T))>::type _ot(ostream &os,
                                                 tuple<T...> const &t) {
  os << (n == 0 ? "" : " ") << get<n>(t);
  _ot<n + 1>(os, t);
}
template <class... T> ostream &operator<<(ostream &os, tuple<T...> const &t) {
  _ot<0>(os, t);
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, pair<T, U> const &p) {
  return os << "(" << p.first << ", " << p.second << ") ";
}
template <class T> ostream &operator<<(ostream &os, vector<T> const &v) {
  rep(i, v.size()) os << v[i] << (i + 1 == (int)v.size() ? "" : " ");
  return os;
}
#ifdef DEBUG
#define dump(...)                                                              \\
  (cerr << #__VA_ARGS__ << " = " << mt(__VA_ARGS__) << " [" << __LINE__ << "]" \\
        << endl)
#else
#define dump(...)
#endif

typedef unsigned long long ull;

#undef MCR
#define MCR Mint const &
template <int M> struct Mint {
  struct zerodiv {};
  struct zeropowzero {};
  int x;
  explicit Mint() : x(0) {}
  explicit Mint(int y) {
    if ((x = y % M + M) >= M)
      x -= M;
  }
  Mint &operator+=(MCR m) {
    if ((x += m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator-=(MCR m) {
    if ((x += M - m.x) >= M)
      x -= M;
    return *this;
  }
  Mint &operator*=(MCR m) {
    x = 1LL * x * m.x % M;
    return *this;
  }
  Mint &operator/=(MCR m) {
    /* !! default x/0 is undefined !! */
    // if(m.x % M == 0) throw zerodiv();
    x = (1LL * x * m.exp(M - 2).x) % M;
    return *this;
  }
  Mint operator+(MCR m) const { return Mint(*this) += m; }
  Mint operator-(MCR m) const { return Mint(*this) -= m; }
  Mint operator*(MCR m) const { return Mint(*this) *= m; }
  Mint operator/(MCR m) const { return Mint(*this) /= m; }
  bool operator<(MCR m) const { return x < m.x; }
  Mint inv() const { return exp(M - 2); }
  Mint exp(long long t) const {
    /* !! default 0^0 = 1 !! */
    // if(x==0 && t==0) throw zeropowzero();
    Mint e = *this, res = Mint(1);
    for (; t; e *= e, t >>= 1)
      if (t & 1)
        res *= e;
    return res;
  }
};
template <int M> ostream &operator<<(ostream &os, Mint<M> m) {
  return os << m.x;
}

int const mod = 1000000007;
typedef Mint<mod> mint;
mint const ZERO(0);
mint const ONE(1);

int main() {
  srand(time(0));
  mint const B(rand());
  string s, t;
  cin >> s >> t;
  set<mint> ok;
  mint hash = ZERO;
  rep(i, t.size()) hash = hash * B + mint(t[i]);
  mint e(1);
  for (int i = t.size() - 1; i >= 0; i--) {
    for (char c = 'a'; c <= 'z'; c++) {
      if (c != t[i]) {
        mint mhash = hash + mint(c - t[i]) * e;
        ok.insert(mhash);
      }
      char C = c ^ 32;
      if (C != t[i]) {
        mint mhash = hash + mint(C - t[i]) * e;
        ok.insert(mhash);
      }
    }
    e *= B;
  }

  assert(ok.size() <= 2 * 26 * t.size());

  int ans = 0;
  hash = ZERO;
  rep(i, t.size()) hash = hash * B + mint(s[i]);
  rep(i, s.size() - t.size() + 1) {
    ans += ok.count(hash);
    hash = hash * B + mint(s[i + t.size()]) - mint(s[i]) * e;
  }
  cout << ans << endl;
}