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

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

#pragma region Macros
#define FOR(i, m, n) for (ll i = (ll)(m); i < (ll)(n); i++)
#define rep(i, n) FOR(i, 0, n)

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

template <class T> string join(const T &v, const string delim = ",") {
  if (v.empty())
    return "";

  ostringstream res;
  res << v[0];
  for (int i = 1; i < v.size(); i++) {
    res << delim << v[i];
  }
  return res.str();
}

#ifdef LOCAL
#define dbg(x) cerr << __LINE__ << ":" << #x << " = " << (x) << endl;
#else
#define dbg
#endif

#pragma endregion Macros
template <long long Mod> struct modint {
  ll n;
  modint(ll x = 0) : n((x + Mod) % Mod) {}

  modint operator+(const modint &r) const { return modint(*this) += r; }
  modint operator-(const modint &r) const { return modint(*this) -= r; }
  modint operator*(const modint &r) const { return modint(*this) *= r; }
  modint operator/(const modint &r) const { return modint(*this) /= r; }
  modint operator+=(const modint &r) {
    n += r.n;
    n %= Mod;
    return *this;
  }
  modint operator-=(const modint &r) {
    n -= r.n;
    n += Mod;
    n %= Mod;
    return *this;
  }
  modint operator*=(const modint &r) {
    n *= r.n;
    n %= Mod;
    return *this;
  }
  modint operator/=(const modint &r) {
    *this *= modint(r).inv();
    return *this;
  }

  modint operator=(const modint &r) { return n = r.n; }
  modint operator==(const modint &r) const { return n == r.n; }
  modint operator!=(const modint &r) const { return n != r.n; }

  modint inv() const { return pow(Mod - 2); }

  modint pow(const ll x) const {
    if (n == 0)
      return modint(0);
    if (x == 0)
      return modint(1);
    if (x == 1)
      return modint(n);

    modint a = modint(*this);
    a = (a * a).pow(x / 2);

    if (x % 2 == 1) {
      a *= n;
    }
    return a;
  }

  friend ostream &operator<<(ostream &os, const modint &x) { return os << x.n; }
  friend istream &operator>>(istream &is, modint &x) { return is >> x.n; }
};

using mint = modint<2019>;

int main() {
  string S;
  cin >> S;

  int N = S.size();

  vector<mint> m(N); // m[i] : Sの[i,N)の部分文字列を、mod 2019した値

  m[N - 1] = S[N - 1] - '0';

  for (int i = N - 2, k = 1; i >= 0; i--, k++) {
    mint s = mint(S[i] - '0') * mint(10).pow(k);
    m[i] = m[i + 1] + s;
  }

  vector<vector<short>> t(
      N + 1,
      vector<short>(2020, 0)); // t[i][j] : [i,N)の、mod 2019がjのものの数

  for (int i = N - 1; i >= 0; i--) {
    t[i][m[i].n]++;
    rep(j, 2020) t[i][j] += t[i + 1][j];
  }

  ll ans = 0;

  for (int i = 0; i < N; i++) {
    ans += t[i + 1][m[i].n];
    if (m[i].n == 0)
      ans++;
  }

  cout << ans << endl;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;
using ll = long long;

#pragma region Macros
#define FOR(i, m, n) for (ll i = (ll)(m); i < (ll)(n); i++)
#define rep(i, n) FOR(i, 0, n)

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

template <class T> string join(const T &v, const string delim = ",") {
  if (v.empty())
    return "";

  ostringstream res;
  res << v[0];
  for (int i = 1; i < v.size(); i++) {
    res << delim << v[i];
  }
  return res.str();
}

#ifdef LOCAL
#define dbg(x) cerr << __LINE__ << ":" << #x << " = " << (x) << endl;
#else
#define dbg
#endif

#pragma endregion Macros
template <long long Mod> struct modint {
  ll n;
  modint(ll x = 0) : n((x + Mod) % Mod) {}

  modint operator+(const modint &r) const { return modint(*this) += r; }
  modint operator-(const modint &r) const { return modint(*this) -= r; }
  modint operator*(const modint &r) const { return modint(*this) *= r; }
  modint operator/(const modint &r) const { return modint(*this) /= r; }
  modint operator+=(const modint &r) {
    n += r.n;
    n %= Mod;
    return *this;
  }
  modint operator-=(const modint &r) {
    n -= r.n;
    n += Mod;
    n %= Mod;
    return *this;
  }
  modint operator*=(const modint &r) {
    n *= r.n;
    n %= Mod;
    return *this;
  }
  modint operator/=(const modint &r) {
    *this *= modint(r).inv();
    return *this;
  }

  modint operator=(const modint &r) { return n = r.n; }
  modint operator==(const modint &r) const { return n == r.n; }
  modint operator!=(const modint &r) const { return n != r.n; }

  modint inv() const { return pow(Mod - 2); }

  modint pow(const ll x) const {
    if (n == 0)
      return modint(0);
    if (x == 0)
      return modint(1);
    if (x == 1)
      return modint(n);

    modint a = modint(*this);
    a = (a * a).pow(x / 2);

    if (x % 2 == 1) {
      a *= n;
    }
    return a;
  }

  friend ostream &operator<<(ostream &os, const modint &x) { return os << x.n; }
  friend istream &operator>>(istream &is, modint &x) { return is >> x.n; }
};

using mint = modint<2019>;

int main() {
  string S;
  cin >> S;

  int N = S.size();

  vector<mint> m(N); // m[i] : Sの[i,N)の部分文字列を、mod 2019した値

  m[N - 1] = S[N - 1] - '0';

  for (int i = N - 2, k = 1; i >= 0; i--, k++) {
    mint s = mint(S[i] - '0') * mint(10).pow(k);
    m[i] = m[i + 1] + s;
  }

  vector<vector<int>> t(
      N + 1, vector<int>(2020, 0)); // t[i][j] : [i,N)の、mod 2019がjのものの数

  for (int i = N - 1; i >= 0; i--) {
    t[i][m[i].n]++;
    rep(j, 2020) t[i][j] += t[i + 1][j];
  }

  ll ans = 0;

  for (int i = 0; i < N; i++) {
    ans += t[i + 1][m[i].n];
    if (m[i].n == 0)
      ans++;
  }

  cout << ans << endl;
}