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

#include <bits/stdc++.h>
using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define ALL(a) (a).begin(), (a).end()

template <typename U, typename T> void chmin(U &x, T y) { x = min(x, y); }

template <typename U, typename T> void chmax(U &x, T y) { x = max(x, y); }

typedef long long int lli;
typedef long double ld;
typedef pair<int, int> P;

const int INF = INT_MAX / 3;
const double EPS = 1e-14;
const int dx[4] = {0, 1, 0, -1}; // {-1,  0,  1, -1, 1, -1, 0, 1};
const int dy[4] = {1, 0, -1, 0}; // {-1, -1, -1,  0, 0,  1, 1, 1};

lli s;

lli pw(lli a, lli n) {
  if (n == 0)
    return 1;
  if (n % 2 == 0)
    return pw(a * a, n / 2);
  return a * pow(a, n - 1);
}

lli width(lli idx, lli base) {
  lli p = 0;
  while (idx >= pw(10, p))
    p++;
  lli val = -((pw(10, p) - 1) / base - idx / base) * p;
  while (p > 0) {
    val += p * (pw(10, p) - pw(10, p - 1)) / base;
    p--;
  }
  return val;
}

lli string_width(lli idx) {
  lli val = width(idx, 1) - width(idx, 3) - width(idx, 5) + width(idx, 15);
  val += (idx / 3 + idx / 5) * 4;
  return val;
}

string fizzbuzz20(lli start) {
  string str;
  for (lli n = start; n < start + 20; n++) {
    if (n % 15 == 0)
      str += "FizzBuzz";
    else if (n % 3 == 0)
      str += "Fizz";
    else if (n % 5 == 0)
      str += "Buzz";
    else
      str += to_string(n);
  }
  return str;
}

int main() {
  cout << fixed << setprecision(10);
  cin >> s;
  lli lb = 0, ub = 1e17;
  while (ub - lb > 1) {
    lli mid = (lb + ub) / 2;
    if (string_width(mid) >= s)
      ub = mid;
    else
      lb = mid;
  }
  string ans = fizzbuzz20(lb + 1);

  ans = ans.substr(s - string_width(lb) - 1);
  cout << ans.substr(0, 20) << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define RFOR(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define REP(i, n) for (int i = 0; i < (n); i++)
#define RREP(i, n) for (int i = (n)-1; i >= 0; i--)
#define ALL(a) (a).begin(), (a).end()

template <typename U, typename T> void chmin(U &x, T y) { x = min(x, y); }

template <typename U, typename T> void chmax(U &x, T y) { x = max(x, y); }

typedef long long int lli;
typedef long double ld;
typedef pair<int, int> P;

const int INF = INT_MAX / 3;
const double EPS = 1e-14;
const int dx[4] = {0, 1, 0, -1}; // {-1,  0,  1, -1, 1, -1, 0, 1};
const int dy[4] = {1, 0, -1, 0}; // {-1, -1, -1,  0, 0,  1, 1, 1};

lli s;

lli pw(lli a, lli n) {
  if (n == 0)
    return 1;
  if (n % 2 == 0)
    return pw(a * a, n / 2);
  return a * pow(a, n - 1);
}

lli width(lli idx, lli base) {
  lli p = 0;
  while (idx >= pw(10, p))
    p++;
  lli val = -((pw(10, p) - 1) / base - idx / base) * p;
  while (p > 0) {
    val += p * (pw(10, p) - pw(10, p - 1)) / base;
    p--;
  }
  return val;
}

lli string_width(lli idx) {
  lli val = width(idx, 1) - width(idx, 3) - width(idx, 5) + width(idx, 15);
  val += (idx / 3 + idx / 5) * 4;
  return val;
}

string fizzbuzz20(lli start) {
  string str;
  FOR(n, start, start + 20) {
    if (n % 15 == 0)
      str += "FizzBuzz";
    else if (n % 3 == 0)
      str += "Fizz";
    else if (n % 5 == 0)
      str += "Buzz";
    else
      str += to_string(n);
  }
  return str;
}

int main() {
  cout << fixed << setprecision(10);
  cin >> s;
  lli lb = 0, ub = 1e17;
  while (ub - lb > 1) {
    lli mid = (lb + ub) / 2;
    if (string_width(mid) >= s)
      ub = mid;
    else
      lb = mid;
  }
  string ans = fizzbuzz20(lb + 1);

  /*cout << lb << " " << ub << " " << ans << endl;
  cout << string_width(lb + 1) << endl;*/

  ans = ans.substr(s - string_width(lb) - 1);
  cout << ans.substr(0, 20) << endl;
  return 0;
}