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

#include <bits/stdc++.h>

#define debug(x)                                                               \\
  cout << "DEBUG"                                                              \\
       << " " << #x << ":" << x << '\\n'
#define rep(i, n)                                                              \\
  for (int_fast32_t i = 0; i < ((int_fast32_t)(n)); i++) // 0-indexed昇順
#define rep1(i, n)                                                             \\
  for (int_fast32_t i = 1; i <= ((int_fast32_t)(n)); i++) // 1-indexed昇順
#define rrep(i, n)                                                             \\
  for (int_fast32_t i = ((int_fast32_t)(n)-1); i >= 0; i--) // 0-indexed降順
#define rrep1(i, n)                                                            \\
  for (int_fast32_t i = ((int_fast32_t)(n)); i >= 1; i--) // 1-indexed降順
#define all(x) (x).begin(), (x).end()

using namespace std;

template <typename T> using vec = vector<T>;
using i32 = int_fast32_t;
using i64 = int_fast64_t;
using u32 = uint_fast32_t;
using u64 = uint_fast64_t;
using ll = long long;
using ld = long double;
using vi = vec<int_fast32_t>;
using vl = vec<int_fast64_t>;
using vld = vec<ld>;
using vii = vec<vi>; // 2次元配列
using PII = pair<int_fast32_t, int_fast32_t>;

template <class T> using maxheap = std::priority_queue<T>;
template <class T>
using minheap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <class T, class U> inline bool chmax(T &a, const U &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T, class U> inline bool chmin(T &a, const U &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

const ld Pi = std::acos(-1.0L);
constexpr ll infll = (1LL << 62) - 1;
constexpr int inf = (1 << 30) - 1;
const int mod = 2019;
// const int mod = 998244353;

/*MOD int=============================*/
template <std::int_fast64_t Mod> class modint {
  using i64 = std::int_fast64_t;

public:
  i64 val;
  // constructor
  constexpr modint(const i64 p = 0) noexcept
      : val(p >= 0 ? p % Mod : (Mod + (p % Mod)) % Mod) {}

  // std::cin, std::cout
  friend std::ostream &operator<<(std::ostream &os, const modint &x) {
    return os << x.val;
  }
  friend std::istream &operator>>(std::istream &is, modint &x) {
    is >> x.val;
    x.val %= Mod;
    if (x.val < 0)
      x.val += Mod; // <- 負数対応
    return is;
  }

  // operator
  constexpr modint operator+(const modint b) const noexcept {
    return modint(*this) += b;
  }

  constexpr modint operator-(const modint b) const noexcept {
    return modint(*this) -= b;
  }

  constexpr modint operator*(const modint b) const noexcept {
    return modint(*this) *= b;
  }

  constexpr modint operator/(const modint b) const noexcept {
    return modint(*this) /= b;
  }

  constexpr modint operator-() const noexcept { return modint() - *this; }

  constexpr bool operator==(const modint &b) const noexcept {
    return this->val == b.val;
  }

  constexpr bool operator!=(const modint &b) const noexcept {
    return this->val != b.val;
  }

  constexpr modint &operator=(const modint b) noexcept {
    val = b.val;
    return *this;
  }
  constexpr modint &operator=(const i64 b) noexcept {
    val = modint<Mod>(b).val;
    return *this;
  }
  constexpr modint &operator+=(const modint b) noexcept {
    if ((val += b.val) >= Mod)
      val -= Mod;
    return *this;
  }
  constexpr modint &operator-=(const modint b) noexcept {
    if (val < b.val)
      val += Mod;
    val -= b.val;
    return *this;
  }
  constexpr modint &operator*=(const modint b) noexcept {
    val = val * b.val % Mod;
    return *this;
  }
  constexpr modint &operator/=(modint b) noexcept {
    val *= b.inverse().val;
    val %= Mod;
    return *this;
  }
  constexpr modint inverse() noexcept {
    i64 m = Mod, u = 1, v = 0, t = 1;
    while (m) {
      t = val / m;
      val -= t * m;
      std::swap(val, m);
      u -= t * v;
      std::swap(u, v);
    }
    return modint(u);
  }
  // calc val^n
  constexpr modint pow(i64 n) noexcept {
    modint res = 1, a = val;
    while (n > 0) {
      if (n & 1)
        res = res * a;
      a = a * a;
      n >>= 1;
    }
    return res;
  }
};
using mint = modint<mod>;

/*FUNCs=================================================*/

/*MAIN==================================================*/
signed main() {
  int START_TIME = clock();
  cin.tie(nullptr);
  ios::sync_with_stdio(false); // cin cout 高速化
  //    cout << fixed << setprecision(15);

  string s;
  cin >> s;

  map<i32, i32> mp;
  mp[0] = 1;
  mint modOf10s = 1;
  mint modOfSubString = 0;

  for (i32 i = s.size() - 1; i >= 0; --i) {
    modOfSubString = modOf10s * (s[i] - '0') + modOfSubString;
    ++mp[modOfSubString.val];

    modOf10s *= 10;
  }

  i64 answer = 0;
  for (auto p : mp) {
    answer += (p.second - 1) * p.second / 2;
  }

  cout << answer << '\\n';

  // printf("ExecutionTime: %d
  // /ms\\n",1000*(int)((clock()-START_TIME)/CLOCKS_PER_SEC));
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>

#define debug(x)                                                               \\
  cout << "DEBUG"                                                              \\
       << " " << #x << ":" << x << '\\n'
#define rep(i, n)                                                              \\
  for (int_fast32_t i = 0; i < ((int_fast32_t)(n)); i++) // 0-indexed昇順
#define rep1(i, n)                                                             \\
  for (int_fast32_t i = 1; i <= ((int_fast32_t)(n)); i++) // 1-indexed昇順
#define rrep(i, n)                                                             \\
  for (int_fast32_t i = ((int_fast32_t)(n)-1); i >= 0; i--) // 0-indexed降順
#define rrep1(i, n)                                                            \\
  for (int_fast32_t i = ((int_fast32_t)(n)); i >= 1; i--) // 1-indexed降順
#define all(x) (x).begin(), (x).end()

using namespace std;

template <typename T> using vec = vector<T>;
using i32 = int_fast32_t;
using i64 = int_fast64_t;
using u32 = uint_fast32_t;
using u64 = uint_fast64_t;
using ll = long long;
using ld = long double;
using vi = vec<int_fast32_t>;
using vl = vec<int_fast64_t>;
using vld = vec<ld>;
using vii = vec<vi>; // 2次元配列
using PII = pair<int_fast32_t, int_fast32_t>;

template <class T> using maxheap = std::priority_queue<T>;
template <class T>
using minheap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <class T, class U> inline bool chmax(T &a, const U &b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T, class U> inline bool chmin(T &a, const U &b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}

const ld Pi = std::acos(-1.0L);
constexpr ll infll = (1LL << 62) - 1;
constexpr int inf = (1 << 30) - 1;
const int mod = 1000000007;
// const int mod = 998244353;

/*FUNCs=================================================*/

/*MAIN==================================================*/
signed main() {
  int START_TIME = clock();
  cin.tie(nullptr);
  ios::sync_with_stdio(false); // cin cout 高速化
  //    cout << fixed << setprecision(15);

  string s, tmp;
  cin >> s;
  i32 n = s.size();
  set<string> kouho;
  for (i32 i = 1; i < 10000; i++) {
    tmp = to_string(2019 * i);
    for (auto ch : tmp)
      if (ch == '0')
        continue;
    kouho.insert(tmp);
  }

  string init;
  tmp = init;
  i32 cnt = 0;
  for (i32 i = 0; i < n; ++i) { // i始まりの2019文字列を探せ
    for (i32 j = i; j < n;) {
      bool did = 0;
      for (auto ss : kouho) {
        if (s.substr(j, ss.size()) == ss) {
          ++cnt;
          j += ss.size();
          did = 1;
          break;
        }
      }
      if (!did)
        break;
    }
  }

  cout << cnt << '\\n';

  // printf("ExecutionTime: %d
  // /ms\\n",1000*(int)((clock()-START_TIME)/CLOCKS_PER_SEC));
}