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

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, begin, end) for (ll i = (begin); i < (end); i++)
#define REP(i, n) FOR(i, 0, n)
#define IFOR(i, begin, end) for (ll i = (begin)-1; i >= (end); i--)
#define IREP(i, n) IFOR(i, n, 0)
#define SORT(a) sort(a.begin(), a.end())
#define ISORT(a) sort(a.begin(), a.end(), greater<ll>())
#define REVERSE(a) reverse(a.begin(), a.end())
#define debug(x) cout << #x << "=" << x << endl;
#define vdebug(v)                                                              \\
  cout << #v << "=(" << v[0];                                                  \\
  FOR(i_debug, 1, v.size()) { cout << "," << v[i_debug]; }                     \\
  cout << ")" << endl;
#define mdebug(m)                                                              \\
  cout << #m << "=" << endl;                                                   \\
  REP(i_debug, m.size()) {                                                     \\
    REP(j_debug, m[i_debug].size()) { cout << m[i_debug][j_debug] << ","; }    \\
    cout << endl;                                                              \\
  }
#define Lower_bound(v, x)                                                      \\
  distance(v.begin(), lower_bound(v.begin(), v.end(), x))
#define Upper_bound(v, x)                                                      \\
  distance(v.begin(), upper_bound(v.begin(), v.end(), x))
#define Max(a, b) a = max(a, b)
#define Min(a, b) a = min(a, b)

#define ll long long
// #define f first
// #define s second
#define mp make_pair
#define pb push_back
#define INF 1000000000000000000

using vec = vector<ll>;
using mat = vector<vec>;
using Pii = pair<ll, ll>;
using PiP = pair<ll, Pii>;
using PPi = pair<Pii, ll>;
using bvec = vector<bool>;
using Pvec = vector<Pii>;

template <typename T> void readv(vector<T> &a) { REP(i, a.size()) cin >> a[i]; }
void readv_m1(vector<int> &a) {
  REP(i, a.size()) {
    cin >> a[i];
    a[i]--;
  }
}

ll mod = 1000000007;

// https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a#4-%E7%B4%AF%E4%B9%97-an
ll modpow(ll a, ll n, ll mod) {
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

ll ctoi(const char c) {
  switch (c) {
  case '0':
    return 0;
  case '1':
    return 1;
  case '2':
    return 2;
  case '3':
    return 3;
  case '4':
    return 4;
  case '5':
    return 5;
  case '6':
    return 6;
  case '7':
    return 7;
  case '8':
    return 8;
  case '9':
    return 9;
  default:
    return -1;
  }
}

int main() {
  vector<vector<int>> dp(2, vector<int>(2019, 0));

  string S;
  cin >> S;
  ll ans = 0;
  REP(i, S.size()) {
    dp[1][ctoi(S[i])] += 1;
    REP(j, 2019) {
      ll nextj = (j * 10 + ctoi(S[i])) % 2019;
      dp[1][nextj] += dp[0][j];
      // if (nextj == 0 && dp[0][j] != 0) {
      //   cout << "nextj-" << nextj << endl;
      //   cout << "j-" << j << endl;
      // }
    }
    ans += dp[1][0];
    // cout << "ans" << ans << endl;
    REP(j, 2019) {
      dp[0][j] = dp[1][j];
      dp[1][j] = 0;
    }
  }
  cout << ans << endl;

  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
#define FOR(i, begin, end) for (ll i = (begin); i < (end); i++)
#define REP(i, n) FOR(i, 0, n)
#define IFOR(i, begin, end) for (ll i = (begin)-1; i >= (end); i--)
#define IREP(i, n) IFOR(i, n, 0)
#define SORT(a) sort(a.begin(), a.end())
#define ISORT(a) sort(a.begin(), a.end(), greater<ll>())
#define REVERSE(a) reverse(a.begin(), a.end())
#define debug(x) cout << #x << "=" << x << endl;
#define vdebug(v)                                                              \\
  cout << #v << "=(" << v[0];                                                  \\
  FOR(i_debug, 1, v.size()) { cout << "," << v[i_debug]; }                     \\
  cout << ")" << endl;
#define mdebug(m)                                                              \\
  cout << #m << "=" << endl;                                                   \\
  REP(i_debug, m.size()) {                                                     \\
    REP(j_debug, m[i_debug].size()) { cout << m[i_debug][j_debug] << ","; }    \\
    cout << endl;                                                              \\
  }
#define Lower_bound(v, x)                                                      \\
  distance(v.begin(), lower_bound(v.begin(), v.end(), x))
#define Upper_bound(v, x)                                                      \\
  distance(v.begin(), upper_bound(v.begin(), v.end(), x))
#define Max(a, b) a = max(a, b)
#define Min(a, b) a = min(a, b)

#define ll long long
// #define f first
// #define s second
#define mp make_pair
#define pb push_back
#define INF 1000000000000000000

using vec = vector<ll>;
using mat = vector<vec>;
using Pii = pair<ll, ll>;
using PiP = pair<ll, Pii>;
using PPi = pair<Pii, ll>;
using bvec = vector<bool>;
using Pvec = vector<Pii>;

template <typename T> void readv(vector<T> &a) { REP(i, a.size()) cin >> a[i]; }
void readv_m1(vector<int> &a) {
  REP(i, a.size()) {
    cin >> a[i];
    a[i]--;
  }
}

ll mod = 1000000007;

// https://qiita.com/drken/items/3b4fdf0a78e7a138cd9a#4-%E7%B4%AF%E4%B9%97-an
ll modpow(ll a, ll n, ll mod) {
  ll res = 1;
  while (n > 0) {
    if (n & 1)
      res = res * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return res;
}

ll ctoi(const char c) {
  switch (c) {
  case '0':
    return 0;
  case '1':
    return 1;
  case '2':
    return 2;
  case '3':
    return 3;
  case '4':
    return 4;
  case '5':
    return 5;
  case '6':
    return 6;
  case '7':
    return 7;
  case '8':
    return 8;
  case '9':
    return 9;
  default:
    return -1;
  }
}

int main() {
  vector<vector<int>> dp(200005, vector<int>(2019, 0));

  string S;
  cin >> S;
  REP(i, S.size()) {
    dp[i + 1][ctoi(S[i])] += 1;
    REP(j, 2019) {
      ll nextj = (j * 10 + ctoi(S[i])) % 2019;
      // if (nextj == 0) {
      //   // cout << j << endl;
      //   // cout << dp[i][j] << endl;
      // }
      dp[i + 1][nextj] += dp[i][j];
      // dp[i + 1][j] += dp[i][j];
    }
    // cout << dp[i + 1][0] << endl;
  }

  // cout << dp[8][0] << endl;
  ll ans = 0;
  REP(i, S.size() + 1) { ans += dp[i][0]; }
  cout << ans << endl;

  return 0;
}