Problem p02992 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
namespace mint {
int md = 1e9 + 7;
inline void add(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a += b;
  if (a >= md)
    a -= md;
}
inline void sub(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a -= b;
  if (a < 0)
    a += md;
}
inline int sum(int a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  add(a, b);
  return a;
}
inline int dif(int a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  sub(a, b);
  return a;
}
template <class... A> inline int prod(A... args) {
  long long ret = 1;
  for (int a : initializer_list<int>{args...}) {
    assert(0 <= a && a < md);
    ret *= a;
    ret %= md;
  }
  return (int)(ret % md);
}
inline void mul(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a = prod(a, b);
}
inline int inv(int a) {
  assert(0 <= a && a < md);
  a %= md;
  if (a < 0)
    a += md;
  int b = md, u = 0, v = 1;
  while (a) {
    int t = b / a;
    b -= a * t;
    swap(a, b);
    u -= v * t;
    swap(u, v);
  }
  assert(b == 1);
  if (u < 0)
    u += md;
  return u;
}
inline int quot(int a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  return prod(a, inv(b));
}
inline void div(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a = quot(a, b);
}
inline int pow(int a, long long b) {
  assert(0 <= a && a < md);
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1)
      mul(res, a);
    mul(a, a);
  }
  return res;
}
namespace factorials {
int sz;
vector<int> fact, finv;
void init(int n) {
  sz = n;
  fact.resize(n);
  finv.resize(n);
  fact[0] = 1;
  for (int i = 1; i < n; i++)
    fact[i] = prod(fact[i - 1], i);
  finv[n - 1] = inv(fact[n - 1]);
  for (int i = n - 2; i >= 0; i--)
    finv[i] = prod(finv[i + 1], i + 1);
}
} // namespace factorials
inline int fct(int i) {
  using namespace factorials;
  assert(0 <= i && i < sz);
  return fact[i];
}
inline int fnv(int i) {
  using namespace factorials;
  assert(0 <= i && i < sz);
  return finv[i];
}
inline int binom(int n, int k) {
  using namespace factorials;
  assert(0 <= n && n < sz);
  if (0 < k || n < k)
    return 0;
  return prod(fact[n], finv[k], finv[n - k]);
}
} // namespace mint
int main() {
  std::cin.tie(0);
  std::cin.sync_with_stdio(false);
  int n, k;
  std::cin >> n >> k;
  int sqrt = [n] {
    auto ck = [&](int x) { return x * x <= n; };
    int ok = 0, ng = n + 1, md;
    while (abs(ok - ng) > 1) {
      md = (ok + ng) >> 1;
      if (ck(md))
        ok = md;
      else
        ng = md;
    }
    return ok;
  }();
  std::vector<int> a = [n, sqrt] {
    std::vector<int> b(sqrt);
    std::iota(b.begin(), b.end(), 1);
    auto c = b;
    std::for_each(c.begin(), c.end(), [n](int &x) { x = n / x; });
    std::reverse(c.begin(), c.end());
    if (b.back() == c.front())
      c.erase(c.begin());
    b.insert(b.end(), c.begin(), c.end());
    return b;
  }();
  int N = a.size();
  assert(N == sqrt * 2 || N == sqrt * 2 - 1);
  assert(a[0] == 1);
  assert(a[N - 1] == n);
  auto w = a;
  for (int i = N - 1; i >= 1; i--) {
    w[i] -= w[i - 1];
  }
  auto lb = [&](int x) {
    if (x <= sqrt)
      return x - 1;
    else
      return N - (n / x);
  };
  std::vector<int> dp(N, 1);
  auto make_cum = [&](const std::vector<int> &x) {
    assert(((int)x.size() == N));
    std::vector<int> y(N + 1, 0);
    for (int i = 1; i <= N; i++) {
      y[i] = mint::sum(y[i - 1], mint::prod(x[i - 1], w[i - 1]));
    }
    return y;
  };
  auto cum = make_cum(dp);
  auto sum = [&](int x) {
    assert(1 <= x && x <= n);
    int i = lb(x);
    assert(0 <= i && i < N);
    assert(x <= a[i] && (i == 0 || a[i - 1] < x));
    int ret = cum[i + 1];
    mint::dif(ret, mint::prod(dp[i], a[i] - x));
    return ret;
  };
  auto renew = [&] {
    std::vector<int> new_dp(N);
    for (int i = 0; i < N; i++) {
      new_dp[i] = sum(n / a[i]);
    }
    dp = new_dp;
    cum = make_cum(dp);
  };
  for (int i = 0; i < k - 1; i++)
    renew();
  std::cout << sum(n) << std::endl;
  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
namespace mint {
int md = 1e9 + 7;
inline void add(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a += b;
  if (a >= md)
    a -= md;
}
inline void sub(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a -= b;
  if (a < 0)
    a += md;
}
inline int sum(int a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  add(a, b);
  return a;
}
inline int dif(int a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  sub(a, b);
  return a;
}
template <class... A> inline int prod(A... args) {
  long long ret = 1;
  for (int a : initializer_list<int>{args...}) {
    assert(0 <= a && a < md);
    ret *= a;
    ret %= md;
  }
  return (int)(ret % md);
}
inline void mul(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a = prod(a, b);
}
inline int inv(int a) {
  assert(0 <= a && a < md);
  a %= md;
  if (a < 0)
    a += md;
  int b = md, u = 0, v = 1;
  while (a) {
    int t = b / a;
    b -= a * t;
    swap(a, b);
    u -= v * t;
    swap(u, v);
  }
  assert(b == 1);
  if (u < 0)
    u += md;
  return u;
}
inline int quot(int a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  return prod(a, inv(b));
}
inline void div(int &a, int b) {
  assert(0 <= a && a < md && 0 <= b && b < md);
  a = quot(a, b);
}
inline int pow(int a, long long b) {
  assert(0 <= a && a < md);
  int res = 1;
  for (; b; b >>= 1) {
    if (b & 1)
      mul(res, a);
    mul(a, a);
  }
  return res;
}
namespace factorials {
int sz;
vector<int> fact, finv;
void init(int n) {
  sz = n;
  fact.resize(n);
  finv.resize(n);
  fact[0] = 1;
  for (int i = 1; i < n; i++)
    fact[i] = prod(fact[i - 1], i);
  finv[n - 1] = inv(fact[n - 1]);
  for (int i = n - 2; i >= 0; i--)
    finv[i] = prod(finv[i + 1], i + 1);
}
} // namespace factorials
inline int fct(int i) {
  using namespace factorials;
  assert(0 <= i && i < sz);
  return fact[i];
}
inline int fnv(int i) {
  using namespace factorials;
  assert(0 <= i && i < sz);
  return finv[i];
}
inline int binom(int n, int k) {
  using namespace factorials;
  assert(0 <= n && n < sz);
  if (0 < k || n < k)
    return 0;
  return prod(fact[n], finv[k], finv[n - k]);
}
} // namespace mint
int main() {
  std::cin.tie(0);
  std::cin.sync_with_stdio(false);
  int n, k;
  std::cin >> n >> k;
  int sqrt = [n] {
    auto ck = [&](long long x) { return x * x <= n; };
    int ok = 0, ng = n + 1, md;
    while (abs(ok - ng) > 1) {
      md = (ok + ng) >> 1;
      if (ck(md))
        ok = md;
      else
        ng = md;
    }
    return ok;
  }();
  std::vector<int> a = [n, sqrt] {
    std::vector<int> b(sqrt);
    std::iota(b.begin(), b.end(), 1);
    auto c = b;
    std::for_each(c.begin(), c.end(), [n](int &x) { x = n / x; });
    std::reverse(c.begin(), c.end());
    if (b.back() == c.front())
      c.erase(c.begin());
    b.insert(b.end(), c.begin(), c.end());
    return b;
  }();
  int N = a.size();
  assert(N == sqrt * 2 || N == sqrt * 2 - 1);
  assert(a[0] == 1);
  assert(a[N - 1] == n);
  auto w = a;
  for (int i = N - 1; i >= 1; i--) {
    w[i] -= w[i - 1];
  }
  auto lb = [&](int x) {
    if (x <= sqrt)
      return x - 1;
    else
      return N - (n / x);
  };
  std::vector<int> dp(N, 1);
  auto make_cum = [&](const std::vector<int> &x) {
    assert(((int)x.size() == N));
    std::vector<int> y(N + 1, 0);
    for (int i = 1; i <= N; i++) {
      y[i] = mint::sum(y[i - 1], mint::prod(x[i - 1], w[i - 1]));
    }
    return y;
  };
  auto cum = make_cum(dp);
  auto sum = [&](int x) {
    assert(1 <= x && x <= n);
    int i = lb(x);
    assert(0 <= i && i < N);
    assert(x <= a[i] && (i == 0 || a[i - 1] < x));
    int ret = cum[i + 1];
    mint::dif(ret, mint::prod(dp[i], a[i] - x));
    return ret;
  };
  auto renew = [&] {
    std::vector<int> new_dp(N);
    for (int i = 0; i < N; i++) {
      new_dp[i] = sum(n / a[i]);
    }
    dp = new_dp;
    cum = make_cum(dp);
  };
  for (int i = 0; i < k - 1; i++)
    renew();
  std::cout << sum(n) << std::endl;
  return 0;
}