Problem p02992 (C++)

Buggy submission (status: Runtime Error):
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
using ll = long long int;
using int64 = long long int;

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

// ModInt begin

using ll = long long;
template <ll mod> struct ModInt {
  ll v;
  ll mod_pow(ll x, ll n) const {
    return (!n) ? 1 : (mod_pow((x * x) % mod, n / 2) * ((n & 1) ? x : 1)) % mod;
  }
  ModInt(ll a = 0) : v(a >= mod ? a % mod : a) {}
  ModInt operator+(const ModInt &b) const {
    return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
  }
  ModInt operator-() const { return ModInt(-v); }
  ModInt operator-(const ModInt &b) const {
    return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
  }
  ModInt operator*(const ModInt &b) const { return (v * b.v) % mod; }
  ModInt operator/(const ModInt &b) const {
    return (v * mod_pow(b.v, mod - 2)) % mod;
  }

  bool operator==(const ModInt &b) const { return v == b.v; }
  ModInt &operator+=(const ModInt &b) {
    v += b.v;
    if (v >= mod)
      v -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &b) {
    v -= b.v;
    if (v < 0)
      v += mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &b) {
    (v *= b.v) %= mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &b) {
    (v *= mod_pow(b.v, mod - 2)) %= mod;
    return *this;
  }
  ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
  // operator int() const { return int(v); }
  // operator long long int() const { return v; }
};

template <ll mod> ostream &operator<<(ostream &out, ModInt<mod> a) {
  return out << a.v;
}
template <ll mod> istream &operator>>(istream &in, ModInt<mod> &a) {
  in >> a.v;
  return in;
}

// ModInt end

using mint = ModInt<MOD>;
mint dp[100][31700 * 2], coeff[31700];
int main() {
  int N, K;
  cin >> N >> K;
  dp[0][1] = mint(1);

  int sq = 1;
  while (sq * sq < N)
    sq++;
  if (sq * sq > N)
    sq--;

  for (int i = 1; i <= sq; i++) {
    int v = N / i;
    coeff[i] = mint(max(0, v - sq));
  }
  for (int i = 1; i <= sq; i++) {
    coeff[i] -= coeff[i + 1];
  }

  for (int i = 0; i < K; i++) {
    for (int x = 1; x <= sq; x++) {
      // 1 から sq まで全部一様に足す (いもす的に)
      dp[i + 1][1] += dp[i][x];
      dp[i + 1][sq + 1] -= dp[i][x];

      // dp[i][sq+x] にある値を然るべきところに配る
      dp[i + 1][1] += dp[i][sq + x] * coeff[x];
      dp[i + 1][x + 1] -= dp[i][sq + x] * coeff[x];

      // dp[i+1][sq+x] に値を配る
      dp[i + 1][sq + x] += dp[i][x];
      dp[i + 1][sq + sq + 1] -= dp[i][x];
    }
    for (int x = 1; x <= 2 * sq; x++) {
      dp[i + 1][x] += dp[i + 1][x - 1];
    }
  }

  mint ans(0);
  for (int i = 1; i <= sq; i++) {
    mint v = dp[K][i];
    ans += v;
  }

  for (int i = sq; i >= 1; i--) {
    coeff[i] += coeff[i + 1];
  }

  mint sub(0);
  for (int i = sq + 1; i <= 2 * sq; i++) {
    mint v = dp[K][i] - sub;
    sub += v;
    ans += v * coeff[i - sq];
  }
  cout << ans << endl;
  return 0;
}


Fixed submission:
// #define _GLIBCXX_DEBUG // for STL debug (optional)
#include <algorithm>
#include <bitset>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;
using ll = long long int;
using int64 = long long int;

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

// ModInt begin

using ll = long long;
template <ll mod> struct ModInt {
  ll v;
  ll mod_pow(ll x, ll n) const {
    return (!n) ? 1 : (mod_pow((x * x) % mod, n / 2) * ((n & 1) ? x : 1)) % mod;
  }
  ModInt(ll a = 0) : v(a >= mod ? a % mod : a) {}
  ModInt operator+(const ModInt &b) const {
    return (v + b.v >= mod ? ModInt(v + b.v - mod) : ModInt(v + b.v));
  }
  ModInt operator-() const { return ModInt(-v); }
  ModInt operator-(const ModInt &b) const {
    return (v - b.v < 0 ? ModInt(v - b.v + mod) : ModInt(v - b.v));
  }
  ModInt operator*(const ModInt &b) const { return (v * b.v) % mod; }
  ModInt operator/(const ModInt &b) const {
    return (v * mod_pow(b.v, mod - 2)) % mod;
  }

  bool operator==(const ModInt &b) const { return v == b.v; }
  ModInt &operator+=(const ModInt &b) {
    v += b.v;
    if (v >= mod)
      v -= mod;
    return *this;
  }
  ModInt &operator-=(const ModInt &b) {
    v -= b.v;
    if (v < 0)
      v += mod;
    return *this;
  }
  ModInt &operator*=(const ModInt &b) {
    (v *= b.v) %= mod;
    return *this;
  }
  ModInt &operator/=(const ModInt &b) {
    (v *= mod_pow(b.v, mod - 2)) %= mod;
    return *this;
  }
  ModInt pow(ll x) { return ModInt(mod_pow(v, x)); }
  // operator int() const { return int(v); }
  // operator long long int() const { return v; }
};

template <ll mod> ostream &operator<<(ostream &out, ModInt<mod> a) {
  return out << a.v;
}
template <ll mod> istream &operator>>(istream &in, ModInt<mod> &a) {
  in >> a.v;
  return in;
}

// ModInt end

using mint = ModInt<MOD>;
mint dp[101][31700 * 2], coeff[31700];
int main() {
  int N, K;
  cin >> N >> K;
  dp[0][1] = mint(1);

  int sq = 1;
  while (sq * sq < N)
    sq++;
  if (sq * sq > N)
    sq--;

  for (int i = 1; i <= sq; i++) {
    int v = N / i;
    coeff[i] = mint(max(0, v - sq));
  }
  for (int i = 1; i <= sq; i++) {
    coeff[i] -= coeff[i + 1];
  }

  for (int i = 0; i < K; i++) {
    for (int x = 1; x <= sq; x++) {
      // 1 から sq まで全部一様に足す (いもす的に)
      dp[i + 1][1] += dp[i][x];
      dp[i + 1][sq + 1] -= dp[i][x];

      // dp[i][sq+x] にある値を然るべきところに配る
      dp[i + 1][1] += dp[i][sq + x] * coeff[x];
      dp[i + 1][x + 1] -= dp[i][sq + x] * coeff[x];

      // dp[i+1][sq+x] に値を配る
      dp[i + 1][sq + x] += dp[i][x];
      dp[i + 1][sq + sq + 1] -= dp[i][x];
    }
    for (int x = 1; x <= 2 * sq; x++) {
      dp[i + 1][x] += dp[i + 1][x - 1];
    }
  }

  mint ans(0);
  for (int i = 1; i <= sq; i++) {
    mint v = dp[K][i];
    ans += v;
  }

  for (int i = sq; i >= 1; i--) {
    coeff[i] += coeff[i + 1];
  }

  mint sub(0);
  for (int i = sq + 1; i <= 2 * sq; i++) {
    mint v = dp[K][i] - sub;
    sub += v;
    ans += v * coeff[i - sq];
  }
  cout << ans << endl;
  return 0;
}