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

// #define STOPIT
#include <bits/stdc++.h>
#define rep(i, n, m) for (int i = (n); i < (m); i++)
#define rrep(i, n, m) for (int i = (n)-1; i >= (m); i--)
using namespace std;
using ll = long long;

void debug_impl() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) {
  cerr << " " << head;
  debug_impl(tail...);
}
#ifndef STOPIT
#define debug(...)                                                             \\
  do {                                                                         \\
    cerr << boolalpha << "[" << #__VA_ARGS__ << "]:";                          \\
    debug_impl(__VA_ARGS__);                                                   \\
    cerr << std::noboolalpha;                                                  \\
  } while (false)
#else
#define debug(...)                                                             \\
  {}
#endif

template <typename Container, typename Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
istream &operator>>(istream &is, Container &v) {
  for (auto &x : v) {
    is >> x;
  }
  return is;
}

template <typename Container, typename Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
ostream &operator<<(ostream &os, Container const &v) {
  os << "{";
  for (auto it = v.begin(); it != v.end(); it++) {
    os << (it != v.begin() ? "," : "") << *it;
  }
  return os << "}";
}

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

  unordered_map<int, int> remainders;
  ll rem = 0;
  int cnt = 0;
  ll base = 1;
  remainders[0] = 1;
  rrep(i, S.size(), 0) {
    rem += base * (ll)(S[i] - '0');
    rem %= 2019;
    base *= 10;
    base %= 2019;
    // cout << rem << endl;

    cnt += remainders[rem];
    ++remainders[rem];
  }
  cout << cnt << endl;
  return 0;
}


Error: TLE

Fixed submission:

#define STOPIT
#include <bits/stdc++.h>
#define rep(i, n, m) for (int i = (n); i < (m); i++)
#define rrep(i, n, m) for (int i = (n)-1; i >= (m); i--)
using namespace std;
using ll = long long;

void debug_impl() { cerr << endl; }
template <typename Head, typename... Tail>
void debug_impl(Head head, Tail... tail) {
  cerr << " " << head;
  debug_impl(tail...);
}
#ifndef STOPIT
#define debug(...)                                                             \\
  do {                                                                         \\
    cerr << boolalpha << "[" << #__VA_ARGS__ << "]:";                          \\
    debug_impl(__VA_ARGS__);                                                   \\
    cerr << std::noboolalpha;                                                  \\
  } while (false)
#else
#define debug(...)                                                             \\
  {}
#endif

template <typename Container, typename Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
istream &operator>>(istream &is, Container &v) {
  for (auto &x : v) {
    is >> x;
  }
  return is;
}

template <typename Container, typename Value = typename Container::value_type,
          enable_if_t<!is_same<Container, string>::value, nullptr_t> = nullptr>
ostream &operator<<(ostream &os, Container const &v) {
  os << "{";
  for (auto it = v.begin(); it != v.end(); it++) {
    os << (it != v.begin() ? "," : "") << *it;
  }
  return os << "}";
}

int main() {
  string S;
  cin >> S;
  // vector<vector<int>> dp(2019, vector<int>(S.size()+1, 0));
  unordered_map<int, int> dp;
  int res = 0;
  for (int i = 0; i < S.size(); ++i) {
    unordered_map<int, int> dp_next;
    int now = S[i] - '0';
    for (auto elem : dp) {
      int next = (elem.first * 10 + now) % 2019;
      dp_next[next] += elem.second;
    }
    ++dp_next[now];

    res += dp_next[0];
    swap(dp, dp_next);
    // for (int n=1; n<2019; ++n)
    // {
    //     int next = (n*10+now)%2019;
    //     dp[next][i+1] += dp[n][i];
    //     // if (dp[next][i+1]>0)
    //     //     debug(now, next, i+1, dp[next][i+1]);
    // }
    // ++dp[now][i+1];

    // rep(j, 0, 2019)
    //     cout << j << ':' << dp[j][i]  << ' ';
    // cout << endl;
  }

  cout << res << endl;
  return 0;
}