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

#include <bits/stdc++.h>
#include <iomanip>

using namespace std;

typedef long long LL;
typedef long double LD;
typedef pair<int, int> PII;
typedef pair<LL, LL> PLL;
typedef pair<LD, LD> PLDLD;
typedef vector<int> VI;
typedef vector<char> VB;

#define FOR(i, a, b) for (int i = (a); i < (int)(b); ++i)
#define REP(i, n) FOR(i, 0, n)
#define CLR(a) memset((a), 0, sizeof(a))
#define ALL(a) a.begin(), a.end()

const LD eps = 1e-5;
const long long INFLL = (LL)(1e9) * (LL)(1e9);
const int INF = 1e9 / 2;

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

const LL pow(const LL p, const LL q) {
  LL t = 1;
  REP(i, q)
  t *= p;
  return t;
}

template <typename T> struct has_iter {
private:
  template <typename U>
  static constexpr true_type check(typename U::iterator *);
  template <typename U> static constexpr false_type check(...);

public:
  static constexpr bool value = decltype(check<T>(nullptr))::value;
};

template <typename T, typename U = typename T::iterator>
void print(const T &container) {
  auto &&first = begin(container), last = end(container);
  auto &&back = prev(last);
  for (auto e = first; e != last; e = next(e))
    cout << *e << " \\n"[e == back];
}

extern void *enabler;
template <typename Head,
          typename enable_if<!has_iter<Head>::value>::type *& = enabler>
void print(const Head &head) {
  cout << head << endl;
}

template <typename Head, typename... Tail>
void print(const Head &head, const Tail &...tail) {
  cout << head << " ";
  print(tail...);
}

void io_speedup() {
  cin.tie(0);
  ios::sync_with_stdio(false);
}

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  for (T &x : vec)
    is >> x;
  return is;
}

template <typename T> vector<T> read(int n) {
  vector<T> t(n);
  cin >> t;
  return t;
}

template <typename T> T read() {
  T t;
  cin >> t;
  return t;
}

class SA {
private:
  int k;

public:
  const size_t length;
  const string s;
  vector<int> sa;

  SA(const string &_s);

  const size_t size() const { return length; }
  const bool contain(const string &t) const;
  const vector<int> lcp() const;
};

SA::SA(const string &_s) : s(_s), sa(_s.size() + 1), length(_s.size()) {
  iota(sa.begin(), sa.end(), 0);

  vector<int> rank(size() + 1);
  for (int i = 0; i < size(); i++)
    rank[i] = s[i];
  rank[size()] = -1;

  auto sa_comparator = [&](int i, int j) {
    if (rank[i] != rank[j])
      return rank[i] < rank[j];
    int ri = i + k <= size() ? rank[i + k] : -1;
    int rj = j + k <= size() ? rank[j + k] : -1;
    return ri < rj;
  };

  for (k = 1; k <= size(); k *= 2) {
    sort(sa.begin(), sa.end(), sa_comparator);

    vector<int> tmp(size() + 1);
    tmp[sa[0]] = 0;
    for (int i = 1; i <= size(); i++) {
      tmp[sa[i]] = tmp[sa[i - 1]] + (sa_comparator(sa[i - 1], sa[i]) ? 1 : 0);
    }
    rank = move(tmp);
  }
}

const bool SA::contain(const string &t) const {
  int l = 0, r = size();
  while (r - l > 1) {
    int mid = (l + r) / 2;
    if (s.compare(sa[mid], t.size(), t) < 0)
      l = mid;
    else
      r = mid;
  }
  return s.compare(sa[r], t.size(), t) == 0;
}

const vector<int> SA::lcp() const {
  vector<int> rank(size() + 1), lcp(size() + 1);
  for (int i = 0; i <= size(); i++)
    rank[sa[i]] = i;

  int h = 0;
  lcp[0] = 0;
  for (int i = 0; i < size(); i++) {
    int j = sa[rank[i] - 1];

    if (h > 0)
      h--;
    for (; j + h < size() && i + h < size(); h++)
      if (s[j + h] != s[i + h])
        break;

    lcp[rank[i] - 1] = h;
  }

  return lcp;
}
using LL = long long;

template <LL MODULO = 1000000007> class Mod {
private:
  LL value;

  const void Normalize() {
    value = value < 0 ? (value % MODULO + MODULO) : (value % MODULO);
  }

public:
  Mod<MODULO>() : value(0) {}
  Mod<MODULO>(const LL &val) {
    value = val;
    Normalize();
  }

  explicit operator LL() const { return value; }

  const Mod<MODULO> operator-() const { return Mod<MODULO>(MODULO - value); }
  const Mod<MODULO> operator+(const Mod<MODULO> &rhs) const {
    return Mod<MODULO>(value + rhs.value);
  }
  const Mod<MODULO> operator-(const Mod<MODULO> &rhs) const {
    return Mod<MODULO>(value + (-rhs).value);
  }
  const Mod<MODULO> operator*(const Mod<MODULO> &rhs) const {
    return Mod<MODULO>(value * rhs.value);
  }
  Mod<MODULO> &operator+=(const Mod<MODULO> &rhs) {
    return *this = *this + rhs;
  }
  Mod<MODULO> &operator-=(const Mod<MODULO> &rhs) {
    return *this = *this - rhs;
  }
  Mod<MODULO> &operator*=(const Mod<MODULO> &rhs) {
    return *this = *this * rhs;
  }

  Mod<MODULO> pow(LL p) const;

  Mod<MODULO> inv() const { return pow(MODULO - 2); }

  const Mod<MODULO> operator/(const Mod<MODULO> &rhs) const {
    return *this * rhs.inv();
  }
  Mod<MODULO> &operator/=(const Mod<MODULO> &rhs) {
    return *this = *this / rhs;
  }

  const bool operator<(const Mod<MODULO> &rhs) const {
    return value < rhs.value;
  }
  const bool operator==(const Mod<MODULO> &rhs) const {
    return value == rhs.value;
  }
};

template <LL MODULO> Mod<MODULO> Mod<MODULO>::pow(LL p) const {
  Mod<MODULO> tmp = 1, mult = *this;
  while (p) {
    if ((p & 1) > 0)
      tmp *= mult;
    p >>= 1;
    mult *= mult;
  }
  return tmp;
}

namespace std {
template <LL MODULO> ostream &operator<<(ostream &os, const Mod<MODULO> mod) {
  os << (LL)mod;
  return os;
}
}; // namespace std

const LL Mod2 = 1e9 + 9;
int cti(char c) {
  if ('A' <= c && c <= 'Z')
    return c - 'A';
  return c - 'a' + 26;
}
int main() {
  using VM = vector<Mod<>>;
  using VM2 = vector<Mod<Mod2>>;
  auto s = read<string>(), t = read<string>();
  map<pair<Mod<>, Mod<Mod2>>, int> st;
  VM srh1(s.size() + 1), trh1(t.size() + 1);
  VM2 srh2(s.size() + 1), trh2(t.size() + 1);
  int prime = 59;
  REP(i, s.size()) {
    srh1[i + 1] = srh1[i] * prime + cti(s[i]) + 1;
    srh2[i + 1] = srh2[i] * prime + cti(s[i]) + 1;
  }
  REP(i, t.size()) {
    trh1[i + 1] = trh1[i] * prime + cti(t[i]) + 1;
    trh2[i + 1] = trh2[i] * prime + cti(t[i]) + 1;
  }
  REP(i, s.size() - t.size() + 1) {
    Mod<> m1 = srh1[i + t.size()] - srh1[i] * Mod<>(prime).pow(t.size());
    Mod<Mod2> m2 =
        srh2[i + t.size()] - srh2[i] * Mod<Mod2>(prime).pow(t.size());
    auto p = pair<Mod<>, Mod<Mod2>>(m1, m2);
    if (st.find(p) != st.end())
      st[p] = st[p] + 1;
    else
      st[p] = 1;
  }
  int cnt = 0;
  REP(i, t.size())
  REP(j, 52) {
    if (j == cti(t[i]))
      continue;
    Mod<> h1 = trh1[t.size()] +
               Mod<>(j - cti(t[i])) * Mod<>(prime).pow(t.size() - 1 - i);
    Mod<Mod2> h2 = trh2[t.size()] + Mod<Mod2>(j - cti(t[i])) *
                                        Mod<Mod2>(prime).pow(t.size() - 1 - i);
    auto p = pair<Mod<>, Mod<Mod2>>(h1, h2);
    if (st.find(p) != st.end()) {
      cnt += st[p];
      // print(i,j);
    }
  }
  print(cnt);
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<ll, ll> P;

#define each(i, a) for (auto &&i : a)
#define FOR(i, a, b) for (ll i = (a), __last_##i = (b); i < __last_##i; i++)
#define RFOR(i, a, b) for (ll i = (b)-1, __last_##i = (a); i >= __last_##i; i--)
#define REP(i, n) FOR(i, 0, n)
#define RREP(i, n) RFOR(i, 0, n)
#define __GET_MACRO3(_1, _2, _3, NAME, ...) NAME
#define rep(...) __GET_MACRO3(__VA_ARGS__, FOR, REP)(__VA_ARGS__)
#define rrep(...) __GET_MACRO3(__VA_ARGS__, RFOR, RREP)(__VA_ARGS__)
#define pb push_back
#define all(a) (a).begin(), (a).end()
#define chmin(x, v) x = min(x, v)
#define chmax(x, v) x = max(x, v)

const ll linf = 1e18;
const double eps = 1e-12;
const double pi = acos(-1);

template <typename T> istream &operator>>(istream &is, vector<T> &vec) {
  each(x, vec) is >> x;
  return is;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  rep(i, vec.size()) {
    if (i)
      os << " ";
    os << vec[i];
  }
  return os;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<vector<T>> &vec) {
  rep(i, vec.size()) {
    if (i)
      os << endl;
    os << vec[i];
  }
  return os;
}
ll mul(ll a, ll b, ll mod) { return a * b % mod; }
ll add(ll a, ll b, ll mod) { return (a + b) % mod; }
ll sub(ll a, ll b, ll mod) { return (a - b + mod) % mod; }
ll power(ll x, ll n, ll mod) {
  ll res = 1;
  for (ll i = 1; i <= n; i <<= 1) {
    if (i & n)
      res = mul(res, x, mod);
    x = mul(x, x, mod);
  }
  return res;
}
ll inv(ll n, ll mod) { return power(n, mod - 2, mod); }

class RollingHash {
private:
  const ll A, mod;
  const string &str;
  vector<ll> hash;
  vector<ll> make_hash(const string &s, const ll A, const ll mod) {
    vector<ll> res(s.size() + 1, 0);
    ll coe = 1;
    REP(i, s.size()) {
      hash[i + 1] = add(hash[i], mul(coe, s[i], mod), mod);
      coe = mul(coe, A, mod);
    }
    return res;
  }

public:
  RollingHash(const string &s, const ll A, const ll mod)
      : str(s), A(A), mod(mod), hash(make_hash(s, A, mod)) {}
  ll get(ll l, ll r) {
    return mul(sub(hash[r], hash[l], mod), inv(power(A, l, mod), mod), mod);
  }
  ll get(ll l, ll r, ll i, char c) {
    ll res = get(l, r);
    res = sub(res, mul(str[i], power(A, i, mod), mod), mod);
    return add(res, mul(c, power(A, i, mod), mod), mod);
  }
  bool iseq(ll s1, ll s2, ll len) {
    return get(s1, s1 + len) == get(s2, s2 + len);
  }
};

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  const ll A1 = 1007, mod1 = 1e9 + 9;
  const ll A2 = 1009, mod2 = 1e9 + 7;
  string S, T;
  cin >> S >> T;
  RollingHash rhs1(S, A1, mod1);
  const ll n = S.size(), m = T.size();

  string kh = "";
  rep(c, 'a', 'z' + 1) kh += c;
  rep(c, 'A', 'Z' + 1) kh += c;
  set<ll> ans;
  const ll L = 20;
  rep(xx, (kh.size() + L - 1) / L) {
    set<ll> s;
    RollingHash rht1(T, A1, mod1);
    rep(i, m) rep(j, xx * L, min(xx * L + L, ll(kh.size()))) {
      if (kh[j] == T[i])
        continue;
      s.insert(rht1.get(0, m, i, kh[j]));
    }
    rep(i, n - m + 1) {
      if (s.count(rhs1.get(i, i + m)) > 0) {
        ans.insert(i);
      }
    }
  }
  cout << ans.size() << endl;
}