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

#define _GLIBCXX_DEBUG
#include "bits/stdc++.h"
// #include <intrin.h>  //AtCoder (gcc)
// 上ではこれがあると動かない。__popcnt用のincludeファイル。
using namespace std;
using Graph = vector<vector<int>>;

typedef long long ll;
typedef long double ld;

#define int long long
#define rep(i, n) for (long long i = 0; i < (n); i++)
#define sqrt(d) pow((long double)(d), 0.50)

const ll INF = 2e9;
const ll large_P = 1e9 + 7;

// 繰り返し2乗法
// N^aの、Mで割った余りを求める。
ll my_pow(ll N, ll a, ll M) {
  ll tempo;
  if (a == 0) {
    return 1;
  } else {
    if (a % 2 == 0) {
      tempo = my_pow(N, a / 2, M);
      return (tempo * tempo) % M;
    } else {
      tempo = my_pow(N, a - 1, M);
      return (tempo * N) % M;
    }
  }
}

// N_C_a を M で割った余り
ll my_combination(ll N, ll a, ll M) {
  ll answer = 1;

  rep(i, a) {
    answer *= (N - i);
    answer %= M;
  }

  rep(i, a) {
    answer *= my_pow(i + 1, M - 2, M);
    answer %= M;
  }

  return answer;
}

ll my_gcd(ll &a, ll &b) {
  if (b == 0)
    return a;
  ll temp = a % b;
  return my_gcd(b, temp);
}

// long long型 n を、base 進法での、i 桁目の数が入った vector にする。
void ll_to_vector(ll base, ll n, vector<ll> &v) {
  ll tempo = n;

  ll n_digit = floor(log10(n) / log10(base)) + 1;
  v.assign(n_digit, 0);

  // ll n_digit = v.size();

  for (ll i = 0; i < n_digit; i++) {
    v.at(i) = tempo / pow(base, n_digit - 1 - i);
    tempo -= v.at(i) * pow(base, n_digit - 1 - i);
  }
}

int char_to_int(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 0;
  }
}

signed main() {
  string S;
  cin >> S;
  int N = S.size();

  map<int, int> memo;
  memo[0]++;

  int amari = 0;
  int digit = 1;

  rep(i, N) {
    amari = (amari + digit * char_to_int(S.at(N - 1 - i))) % 2019;
    digit = (digit * 10) % 2019;

    memo[amari]++;
    // cout << amari << endl;
  }

  int res = 0;
  for (auto &&iter = memo.begin(); iter != memo.end(); iter++) {
    res += iter->second * (iter->second - 1) / 2;
    // cout << iter->first << " " << iter->second << endl;
  }

  cout << res << endl;
}

Error: TLE

Fixed submission:

#define _GLIBCXX_DEBUG
#include "bits/stdc++.h"
// #include <intrin.h>  //AtCoder (gcc)
// 上ではこれがあると動かない。__popcnt用のincludeファイル。
using namespace std;
using Graph = vector<vector<int>>;

typedef long long ll;
typedef long double ld;

#define int long long
#define rep(i, n) for (long long i = 0; i < (n); i++)
#define sqrt(d) pow((long double)(d), 0.50)

const ll INF = 2e9;
const ll large_P = 1e9 + 7;

// 繰り返し2乗法
// N^aの、Mで割った余りを求める。
ll my_pow(ll N, ll a, ll M) {
  ll tempo;
  if (a == 0) {
    return 1;
  } else {
    if (a % 2 == 0) {
      tempo = my_pow(N, a / 2, M);
      return (tempo * tempo) % M;
    } else {
      tempo = my_pow(N, a - 1, M);
      return (tempo * N) % M;
    }
  }
}

// N_C_a を M で割った余り
ll my_combination(ll N, ll a, ll M) {
  ll answer = 1;

  rep(i, a) {
    answer *= (N - i);
    answer %= M;
  }

  rep(i, a) {
    answer *= my_pow(i + 1, M - 2, M);
    answer %= M;
  }

  return answer;
}

ll my_gcd(ll &a, ll &b) {
  if (b == 0)
    return a;
  ll temp = a % b;
  return my_gcd(b, temp);
}

// long long型 n を、base 進法での、i 桁目の数が入った vector にする。
void ll_to_vector(ll base, ll n, vector<ll> &v) {
  ll tempo = n;

  ll n_digit = floor(log10(n) / log10(base)) + 1;
  v.assign(n_digit, 0);

  // ll n_digit = v.size();

  for (ll i = 0; i < n_digit; i++) {
    v.at(i) = tempo / pow(base, n_digit - 1 - i);
    tempo -= v.at(i) * pow(base, n_digit - 1 - i);
  }
}

int char_to_int(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 0;
  }
}

signed main() {
  string S;
  cin >> S;
  int N = S.size();

  vector<int> memo(N, -1);
  int res = 0;

  vector<int> beki(N + 1, 1);
  for (int i = 1; i < N + 1; i++) {
    beki.at(i) = (beki.at(i - 1) * 10) % 2019;
  }

  if (N < 4)
    res = 0;
  else {
    rep(i, 1) {
      memo.assign(N, -1);
      for (int j = i; j < N; j++) {
        if (j == i)
          memo.at(j) = char_to_int(S.at(i));
        else {
          memo.at(j) = (memo.at(j - 1) * 10 + char_to_int(S.at(j))) % 2019;
          if (memo.at(j) == 0)
            res++;
        }
      }
    }

    for (int i = 1; i < N; i++) {
      for (int j = i; j < N; j++) {
        if ((memo.at(i - 1) * beki.at(j - i + 1) - memo.at(j)) % 2019 == 0)
          res++;
      }
    }
  }

  cout << res << endl;
  // rep(j, N) cout << memo.at(j) << " ";
  // rep(j, N) cout << beki.at(j) << " ";
}