Problem p01555 (C++) — buggy submission, verdict: Runtime Error

#include <iostream>
#include <sstream>
#include <string>

using namespace std;
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef long long LL;

string FB(LL n) {
  string ret = "";
  if (n % 3 == 0)
    ret += "Fizz";
  if (n % 5 == 0)
    ret += "Buzz";
  if (ret == "")
    ret = toString(n);
  return ret;
}

bool is10(LL q) {
  bool flag = true;
  while (q >= 10) {
    if (q % 10)
      flag = false;
    q /= 10;
  }
  if (q != 1)
    flag = false;
  return flag;
}

LL m10(LL q) {
  LL ret = 1;
  while (ret <= q)
    ret *= 10;
  return ret / 10;
}

LL M10(LL q) {
  LL ret = 1;
  while (ret < q)
    ret *= 10;
  return ret;
}

LL len(LL s, LL e) { //[s,e)の文字数
  LL ret;
  if (s >= e)
    return 0LL;
  if (!is10(s))
    return len(m10(s), e) - len(m10(s), s);
  if (s * 10 < e) {
    return len(s, s * 10) + len(s * 10, e);
  } else {
    int digit = 1;
    LL tmp = s;
    while (tmp >= 10) {
      digit++;
      tmp /= 10;
    }
    LL d3, d5, d15;
    d3 = (e - 1) / 3 - (s - 1) / 3;
    d5 = (e - 1) / 5 - (s - 1) / 5;
    d15 = (e - 1) / 15 - (s - 1) / 15;
    return (e - s - d3 - d5 + d15) * digit + (d3 + d5) * 4;
  }
}

int main() {
  LL n;
  string ret = "";
  cin >> n;
  // 2文探索-1
  LL l = 1, u = 2;
  while (len(1, u) < n)
    u *= 2;
  // 2分探索-2
  while (u - l > 1) {
    LL mid = (l + u) / 2;
    if (len(1, mid) < n)
      l = mid;
    else
      u = mid;
  }
  LL tmp = l;
  while (ret.length() < 100)
    ret += FB(tmp++);
  cout << ret.substr(n - len(1, l) - 1, 20) << endl;
  return 0;
}

Error: 0

Fixed submission:

#include <iostream>
#include <sstream>
#include <string>

using namespace std;
template <class T> inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}
typedef long long LL;

string FB(LL n) {
  string ret = "";
  if (n % 3 == 0)
    ret += "Fizz";
  if (n % 5 == 0)
    ret += "Buzz";
  if (ret == "")
    ret = toString(n);
  return ret;
}

bool is10(LL q) {
  bool flag = true;
  while (q >= 10) {
    if (q % 10)
      flag = false;
    q /= 10;
  }
  if (q != 1)
    flag = false;
  return flag;
}

LL m10(LL q) {
  LL ret = 1;
  while (ret <= q)
    ret *= 10;
  return ret / 10;
}

LL M10(LL q) {
  LL ret = 1;
  while (ret < q)
    ret *= 10;
  return ret;
}

LL len(LL s, LL e) { //[s,e)の文字数
  LL ret;
  if (s == e)
    return 0LL;
  if (!is10(s))
    return len(m10(s), e) - len(m10(s), s);
  if (s * 10 < e) {
    return len(s, s * 10) + len(s * 10, e);
  } else {
    int digit = 1;
    LL tmp = s;
    while (tmp >= 10) {
      digit++;
      tmp /= 10;
    }
    LL d3, d5, d15;
    d3 = (e - 1) / 3 - (s - 1) / 3;
    d5 = (e - 1) / 5 - (s - 1) / 5;
    d15 = (e - 1) / 15 - (s - 1) / 15;
    return (e - s - d3 - d5 + d15) * digit + (d3 + d5) * 4;
  }
}

int main() {
  LL n;
  string ret = "";
  cin >> n;
  // 桁数を求める
  LL l = 1, u = 2;
  while (len(1, u) < n)
    u *= 2;
  // 2分探索
  while (u - l > 1) {
    LL mid = (l + u) / 2;
    if (len(1, mid) < n)
      l = mid;
    else
      u = mid;
  }
  if (len(1, l) >= n)
    u = l;
  u--;
  ret += FB(u).substr(FB(u).length() - (len(1, u) - n + 2));
  u++;
  while (ret.size() < 20) {
    ret += FB(u++);
  }
  cout << ret.substr(0, 20) << endl;
  return 0;
}