Problem p02992 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;

using i64 = int64_t;

#define rep(i, x, y)                                                           \
  for (i64 i = i64(x), i##_max_for_repmacro = i64(y);                          \
       i < i##_max_for_repmacro; ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1.01e9;
const i64 inf64 = 4.01e18;
const double eps = 1e-9;

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T, size_t size> void fill(T (&ary)[size], const T &val) {
  fill_n((T *)ary, size, val);
}

template <class T> T lower_gauss(T num, T den) {
  assert(den != 0);
  if (num == 0)
    return 0;
  if (num > 0 and den > 0)
    return num / den;
  if (num < 0 and den > 0)
    return (num - den + 1) / den;
  return lower_gauss(-num, -den);
}

template <class T> T upper_gauss(T num, T den) {
  return lower_gauss(num, den) + (num % den == 0 ? 0 : 1);
}

void solve() {
  const i64 mod = 1'000'000'007;

  i64 N, K;
  cin >> N >> K;

  set<i64> a;
  rep(i, 1, N) {
    if (i * i > N)
      break;
    a.insert(i);
    a.insert(N / i);
  }

  vector<i64> vals;
  for (auto x : a)
    vals.emplace_back(x);

  map<i64, i64> count; // |lower_gauss(N/j) = i : 1<=j<=N| = count[i]
  for (auto i : a) {
    i64 lower; // lower_gauss(N/lower)>=i, lower_gauss(N/(lower-1))>i
    i64 upper; // lower_gauss(N/upper)<i, lower_gauss(N/(upper-1))>=i
    {
      i64 lb = 0; // lower_gauss(N/lb) > i
      i64 ub = N; // lower_gauss(N/ub) <=i
      while (ub - lb > 1) {
        i64 mid = (lb + ub) / 2;
        if (N / mid <= i)
          ub = mid;
        else
          lb = mid;
      }
      lower = ub;
    }
    {
      i64 lb = 1;     // lower_gauss(N/lb) >= i
      i64 ub = N + 1; // upper_gauss(N/ub) < i
      while (ub - lb > 1) {
        i64 mid = (lb + ub) / 2;
        if (N / mid < i)
          ub = mid;
        else
          lb = mid;
      }
      upper = ub;
    }
    assert(N / lower >= i);
    assert(N / upper < i);
    count[i] = upper - lower;
  }
  map<i64, i64> idx;
  rep(i, 0, vals.size()) idx[vals[i]] = i;

  vector<vector<i64>> dp(K, vector<i64>(a.size()));

  dp[0][0] = count[N / vals[0]];
  rep(i, 1, vals.size()) {
    dp[0][i] = (dp[0][i - 1] + count[N / vals[i]]) % mod;
  }

  rep(i, 1, K) {
    dp[i][0] = dp[i - 1][idx[N]];
    rep(j, 1, vals.size()) {
      dp[i][j] = (dp[i][j - 1] +
                  dp[i - 1][idx[N / vals[j]]] * count[N / vals[j]] % mod) %
                 mod;
    }
  }

  cout << dp[K - 1][idx[N]] << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(16);
  solve();
  return 0;
}


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

using i64 = int64_t;

#define rep(i, x, y)                                                           \
  for (i64 i = i64(x), i##_max_for_repmacro = i64(y);                          \
       i < i##_max_for_repmacro; ++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define print(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define print(x)
#endif

const int inf = 1.01e9;
const i64 inf64 = 4.01e18;
const double eps = 1e-9;

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << "(" << p.first << ", " << p.second << ")";
  return os;
}

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
  os << "[";
  for (const auto &v : vec) {
    os << v << ",";
  }
  os << "]";
  return os;
}

template <typename T> bool chmin(T &a, const T &b) {
  if (a > b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T> bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template <typename T, size_t size> void fill(T (&ary)[size], const T &val) {
  fill_n((T *)ary, size, val);
}

template <class T> T lower_gauss(T num, T den) {
  assert(den != 0);
  if (num == 0)
    return 0;
  if (num > 0 and den > 0)
    return num / den;
  if (num < 0 and den > 0)
    return (num - den + 1) / den;
  return lower_gauss(-num, -den);
}

template <class T> T upper_gauss(T num, T den) {
  return lower_gauss(num, den) + (num % den == 0 ? 0 : 1);
}

void solve() {
  const i64 mod = 1'000'000'007;

  i64 N, K;
  cin >> N >> K;

  set<i64> a;
  rep(i, 1, N + 1) {
    if (i * i > N)
      break;
    a.insert(i);
    a.insert(N / i);
  }

  vector<i64> vals;
  for (auto x : a)
    vals.emplace_back(x);

  map<i64, i64> count; // |lower_gauss(N/j) = i : 1<=j<=N| = count[i]
  for (auto i : a) {
    i64 lower; // lower_gauss(N/lower)>=i, lower_gauss(N/(lower-1))>i
    i64 upper; // lower_gauss(N/upper)<i, lower_gauss(N/(upper-1))>=i
    {
      i64 lb = 0; // lower_gauss(N/lb) > i
      i64 ub = N; // lower_gauss(N/ub) <=i
      while (ub - lb > 1) {
        i64 mid = (lb + ub) / 2;
        if (N / mid <= i)
          ub = mid;
        else
          lb = mid;
      }
      lower = ub;
    }
    {
      i64 lb = 1;     // lower_gauss(N/lb) >= i
      i64 ub = N + 1; // upper_gauss(N/ub) < i
      while (ub - lb > 1) {
        i64 mid = (lb + ub) / 2;
        if (N / mid < i)
          ub = mid;
        else
          lb = mid;
      }
      upper = ub;
    }
    assert(N / lower >= i);
    assert(N / upper < i);
    count[i] = upper - lower;
  }
  map<i64, i64> idx;
  rep(i, 0, vals.size()) idx[vals[i]] = i;

  vector<vector<i64>> dp(K, vector<i64>(a.size()));

  dp[0][0] = count[N / vals[0]];
  rep(i, 1, vals.size()) {
    dp[0][i] = (dp[0][i - 1] + count[N / vals[i]]) % mod;
  }

  rep(i, 1, K) {
    dp[i][0] = dp[i - 1][idx[N]];
    rep(j, 1, vals.size()) {
      dp[i][j] = (dp[i][j - 1] +
                  dp[i - 1][idx[N / vals[j]]] * count[N / vals[j]] % mod) %
                 mod;
    }
  }

  cout << dp[K - 1][idx[N]] << endl;
}

int main() {
  std::cin.tie(0);
  std::ios::sync_with_stdio(false);
  cout.setf(ios::fixed);
  cout.precision(16);
  solve();
  return 0;
}