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

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG_MODE
#define DBG(n) n;
#else
#define DBG(n) ;
#endif
#define REP(i, n) for (ll(i) = (0); (i) < (n); ++i)
#define rep(i, s, g) for (ll(i) = (s); (i) < (g); ++i)
#define rrep(i, s, g) for (ll(i) = (s); i >= (g); --(i))
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define SHOW1d(v, n)                                                           \\
  {                                                                            \\
    for (int WWW = 0; WWW < (n); WWW++)                                        \\
      cerr << v[WWW] << ' ';                                                   \\
    cerr << endl << endl;                                                      \\
  }
#define SHOW2d(v, i, j)                                                        \\
  {                                                                            \\
    for (int aaa = 0; aaa < i; aaa++) {                                        \\
      for (int bbb = 0; bbb < j; bbb++)                                        \\
        cerr << v[aaa][bbb] << ' ';                                            \\
      cerr << endl;                                                            \\
    }                                                                          \\
    cerr << endl;                                                              \\
  }
#define ALL(v) v.begin(), v.end()
#define Decimal fixed << setprecision(20)
#define INF 1000000000
#define LLINF 1000000000000000000LL
#define MOD 1000000007

typedef long long ll;
typedef pair<ll, ll> P;

ll n;
ll num;

bool f(ll mid) {
  ll cou = 0;
  ll san = 0;
  ll go = 0;
  ll juugo = 0;
  ll keta = 9;
  ll prev = 0;
  ll kazu = 1;
  ll tmpsan;
  ll tmpgo;
  ll tmpjuugo;
  while (mid > keta) {
    tmpsan = keta / 3 - san;
    tmpgo = keta / 5 - go;
    tmpjuugo = keta / 15 - juugo;
    cou += (tmpsan + tmpgo) * 4;
    cou += (keta - prev - tmpsan - tmpgo + tmpjuugo) * kazu;

    san += tmpsan;
    go += tmpgo;
    juugo += tmpjuugo;
    kazu++;
    prev = keta;
    keta *= 10;
    keta += 9;
  }

  tmpsan = mid / 3 - san;
  tmpgo = mid / 5 - go;
  tmpjuugo = mid / 15 - juugo;
  cou += (tmpsan + tmpgo) * 4;
  cou += (mid - prev - tmpsan - tmpgo + tmpjuugo) * kazu;

  num = cou;
  return n > cou;
}

void m_prinf(ll kazu) {
  string str = "";

  for (ll i = kazu; i < kazu + 20; i++) {
    if (i % 3 == 0) {
      str += "Fizz";
    }
    if (i % 5 == 0) {
      str += "Buzz";
    }
    if (i % 3 != 0 && i % 5 != 0) {
      string tmpstr = "";
      ll tmp = i;
      while (tmp) {
        tmpstr += (char)((tmp % 10) + '0');
        tmp /= 10;
      }
      for (int j = tmpstr.size() - 1; j >= 0; j--) {
        str += tmpstr[j];
      }
    }
  }

  REP(i, str.size()) {
    num++;
    if (num >= n && num < n + 20) {
      cout << str[i];
    }
  }
  cout << endl;
}

int main() {
  cin >> n;

  ll tb = LLINF;
  ll ub = 0;

  while (abs(tb - ub) > 1) {
    ll mid = (tb + ub) / 2;
    if (f(mid))
      ub = mid;
    else
      tb = mid;
  }
  f(ub);
  m_prinf(ub + 1);

  return 0;
}


Error: MLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#ifdef DEBUG_MODE
#define DBG(n) n;
#else
#define DBG(n) ;
#endif
#define REP(i, n) for (ll(i) = (0); (i) < (n); ++i)
#define rep(i, s, g) for (ll(i) = (s); (i) < (g); ++i)
#define rrep(i, s, g) for (ll(i) = (s); i >= (g); --(i))
#define PB push_back
#define MP make_pair
#define FI first
#define SE second
#define SHOW1d(v, n)                                                           \\
  {                                                                            \\
    for (int WWW = 0; WWW < (n); WWW++)                                        \\
      cerr << v[WWW] << ' ';                                                   \\
    cerr << endl << endl;                                                      \\
  }
#define SHOW2d(v, i, j)                                                        \\
  {                                                                            \\
    for (int aaa = 0; aaa < i; aaa++) {                                        \\
      for (int bbb = 0; bbb < j; bbb++)                                        \\
        cerr << v[aaa][bbb] << ' ';                                            \\
      cerr << endl;                                                            \\
    }                                                                          \\
    cerr << endl;                                                              \\
  }
#define ALL(v) v.begin(), v.end()
#define Decimal fixed << setprecision(20)
#define INF 1000000000
#define LLINF 1000000000000000000LL
#define MOD 1000000007

typedef long long ll;
typedef pair<ll, ll> P;

ll n;
ll num;

bool f(ll mid) {
  ll cou = 0;
  ll san = 0;
  ll go = 0;
  ll juugo = 0;
  ll keta = 9;
  ll prev = 0;
  ll kazu = 1;
  ll tmpsan;
  ll tmpgo;
  ll tmpjuugo;
  while (mid > keta) {
    tmpsan = keta / 3 - san;
    tmpgo = keta / 5 - go;
    tmpjuugo = keta / 15 - juugo;
    cou += (tmpsan + tmpgo) * 4;
    cou += (keta - prev - tmpsan - tmpgo + tmpjuugo) * kazu;

    san += tmpsan;
    go += tmpgo;
    juugo += tmpjuugo;
    kazu++;
    prev = keta;
    keta *= 10;
    keta += 9;
  }

  tmpsan = mid / 3 - san;
  tmpgo = mid / 5 - go;
  tmpjuugo = mid / 15 - juugo;
  cou += (tmpsan + tmpgo) * 4;
  cou += (mid - prev - tmpsan - tmpgo + tmpjuugo) * kazu;

  num = cou;
  return n > cou;
}

void m_prinf(ll kazu) {
  string str = "";

  for (int i = kazu; i < kazu + 20; i++) {
    if (i % 3 == 0) {
      str += "Fizz";
    }
    if (i % 5 == 0) {
      str += "Buzz";
    }
    if (i % 3 != 0 && i % 5 != 0) {
      string tmpstr = "";
      ll tmp = i;
      while (tmp) {
        tmpstr += (char)((tmp % 10) + '0');
        tmp /= 10;
      }
      for (int j = tmpstr.size() - 1; j >= 0; j--) {
        str += tmpstr[j];
      }
    }
  }

  REP(i, str.size()) {
    num++;
    if (num >= n && num < n + 20) {
      cout << str[i];
    }
  }
  cout << endl;
}

int main() {
  cin >> n;

  ll tb = LLINF;
  ll ub = 0;

  while (abs(tb - ub) > 1) {
    ll mid = (tb + ub) / 2;
    if (f(mid))
      ub = mid;
    else
      tb = mid;
  }
  f(ub);
  m_prinf(ub + 1);

  return 0;
}