Problem p02992 (C++)

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

#define TRACE(x) x
#define WATCH(x) TRACE(cout << #x " = " << x << endl)
#define WATCHR(a, b)                                                           \
  TRACE(for (auto it = a; it != b;) cout << *(it++) << " "; cout << endl)
#define WATCHC(V)                                                              \
  TRACE({                                                                      \
    cout << #V " = ";                                                          \
    WATCHR(V.begin(), V.end());                                                \
  })

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto &a : x)

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

template <typename T> void ckmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void ckmax(T &a, const T &b) { a = max(a, b); }

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace __input {
template <typename T1, typename T2>
istream &operator>>(istream &i, pair<T1, T2> &p) {
  i >> p.first >> p.second;
  return i;
}
template <typename T, size_t N>
istream &operator>>(istream &i, array<T, N> &v) {
  for (auto &e : v) {
    i >> e;
  }
  return i;
}
template <typename T> istream &operator>>(istream &i, vector<T> &v) {
  for (auto &e : v) {
    i >> e;
  }
  return i;
}
} // namespace __input
using namespace __input;

namespace __output {
template <typename T1, typename T2>
ostream &operator<<(ostream &o, const pair<T1, T2> &t) {
  return o << "(" << t.first << ", " << t.second << ")";
}
template <typename T, size_t N>
ostream &operator<<(ostream &o, const array<T, N> &a) {
  o << "[";
  for (int i = 0; i < N; i++) {
    if (i)
      o << ", ";
    o << a[i];
  }
  return o << "]";
}
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (int i = 0; i < sz(v); i++) {
    if (i)
      o << ", ";
    o << v[i];
  }
  return o << "]";
}
} // namespace __output
using namespace __output;

template <int MOD> struct modnum {
  int v;
  modnum() : v(0) {}
  modnum(ll _v) : v(_v % MOD) {
    if (v < 0)
      v += MOD;
  }
  explicit operator int() const { return v; }
  friend istream &operator>>(istream &i, modnum &n) {
    ll v;
    i >> v;
    n = modnum(v);
    return i;
  }
  friend ostream &operator<<(ostream &o, const modnum &n) { return o << n.v; }

  friend bool operator==(const modnum &a, const modnum &b) {
    return a.v == b.v;
  }
  friend bool operator!=(const modnum &a, const modnum &b) {
    return a.v != b.v;
  }

  modnum &operator+=(const modnum &o) {
    v += o.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  modnum &operator-=(const modnum &o) {
    v -= o.v;
    if (v < 0)
      v += MOD;
    return *this;
  }
  modnum &operator*=(const modnum &o) {
    v = int(ll(v) * ll(o.v) % MOD);
    return *this;
  }
  modnum operator-() {
    modnum res;
    if (v)
      res.v = MOD - v;
    return res;
  }
  friend modnum operator+(const modnum &a, const modnum &b) {
    return modnum(a) += b;
  }
  friend modnum operator-(const modnum &a, const modnum &b) {
    return modnum(a) -= b;
  }
  friend modnum operator*(const modnum &a, const modnum &b) {
    return modnum(a) *= b;
  }

  modnum pow(ll e) const {
    if (e == 0)
      return 1;
    if (e & 1)
      return *this * this->pow(e - 1);
    return (*this * *this).pow(e / 2);
  }

  modnum inv() const {
    int g = MOD, x = 0, y = 1;
    for (int r = v; r != 0;) {
      int q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }

    assert(g == 1);
    assert(y == MOD || y == -MOD);
    return x < 0 ? x + MOD : x;
  }
  modnum &operator/=(const modnum &o) { return (*this) *= o.inv(); }
  friend modnum operator/(const modnum &a, const modnum &b) {
    return modnum(a) /= modnum(b);
  }

  static int totient() {
    int tot = MOD, tmp = MOD;
    for (int p = 2; p * p <= tmp; p++)
      if (tmp % p == 0) {
        tot = tot / p * (p - 1);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot = tot / tmp * (tmp - 1);
    return tot;
  }

  static int primitive_root() {
    if (MOD == 1)
      return 0;
    if (MOD == 2)
      return 1;

    int tot = totient(), tmp = tot;
    vi tot_pr;
    for (int p = 2; p * p <= tmp; p++)
      if (tot % p == 0) {
        tot_pr.push_back(p);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot_pr.push_back(tmp);

    for (int r = 2; r < MOD; r++)
      if (__gcd(r, MOD) == 1) {
        bool root = true;
        for (int p : tot_pr)
          root &= modnum(r).pow(tot / p) != 1;
        if (root)
          return r;
      }
    assert(false);
  }

  static modnum generator() {
    static modnum g = primitive_root();
    return g;
  }
  static int discrete_log(modnum v) {
    static const int M = ceil(sqrt(MOD));
    static unordered_map<int, int> table;
    if (table.empty()) {
      modnum e = 1;
      for (int i = 0; i < M; i++) {
        table[e.v] = i;
        e *= generator();
      }
    }
    static modnum f = generator().pow(totient() - M);

    for (int i = 0; i < M; i++) {
      if (table.count(v.v))
        return table[v.v] + i * M;
      v *= f;
    }
    assert(false);
  }

  static modnum fact(int n) {
    static vector<modnum<MOD>> fact = {1};
    for (assert(n >= 0); fact.size() <= n;)
      fact.push_back(fact.back() * fact.size());
    return fact[n];
  }

  static modnum finv(int n) {
    static vector<modnum<MOD>> finv = {1};
    for (assert(n >= 0); finv.size() <= n;)
      finv.push_back(finv.back() / finv.size());
    return finv[n];
  }

  static modnum ncr(int n, int r) {
    if (r < 0 || n < r)
      return 0;
    return fact(n) * finv(r) * finv(n - r);
  }
};
using mn = modnum<int(1e9 + 7)>;
using vmn = vector<mn>;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);

  int N, K;
  cin >> N >> K;

  if (N == 1) {
    cout << 1 << endl;
    return 0;
  }

  vi bnd;
  for (int i = 1; i * i <= N; i++) {
    bnd.pb(i);
    bnd.pb(N / i);
    bnd.pb(N / i + 1);
  }
  sort(all(bnd));
  bnd.erase(unique(all(bnd)), bnd.end());

  vi uniq{bnd[0]}, divs{N};
  FOR(i, 1, sz(bnd)) {
    uniq.pb(bnd[i]);
    divs.pb(N / bnd[i]);
  }

  int U = sz(uniq);
  F0R(i, U - 1) {
    assert(N / uniq[i] == divs[i]);
    assert(N / uniq[i] == N / (uniq[i + 1] - 1));
  }

  vi canp(U - 1), elts(U - 1);
  F0R(j, U - 1) {
    canp[j] = j ? canp[j - 1] : U - 2;
    while (canp[j] > 0 && (bnd[j + 1] - 1) * (bnd[canp[j] + 1] - 1) > N)
      canp[j]--;
    elts[j] = bnd[j + 1] - bnd[j];
  }

  vmn dp(U - 1, 1);

  F0R(i, K) {
    vmn upd(U - 1, 0);
    F0R(j, sz(upd)) { upd[j] = elts[j] * dp[canp[j]]; }
    F0R(j, sz(upd) - 1)
    upd[j + 1] += upd[j];
    swap(dp, upd);
  }

  cout << dp.back() << endl;

  return 0;
}


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

#define TRACE(x) x
#define WATCH(x) TRACE(cout << #x " = " << x << endl)
#define WATCHR(a, b)                                                           \
  TRACE(for (auto it = a; it != b;) cout << *(it++) << " "; cout << endl)
#define WATCHC(V)                                                              \
  TRACE({                                                                      \
    cout << #V " = ";                                                          \
    WATCHR(V.begin(), V.end());                                                \
  })

#define pb push_back
#define eb emplace_back
#define mp make_pair
#define mt make_tuple
#define lb lower_bound
#define ub upper_bound

#define sz(x) int((x).size())
#define all(x) (x).begin(), (x).end()

#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for (int i = 0; i < (a); i++)
#define FORd(i, a, b) for (int i = (b)-1; i >= (a); i--)
#define F0Rd(i, a) for (int i = (a)-1; i >= 0; i--)
#define trav(a, x) for (auto &a : x)

using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using vll = vector<ll>;
using vvll = vector<vll>;
using vb = vector<bool>;
using vd = vector<double>;
using vs = vector<string>;

template <typename T> void ckmin(T &a, const T &b) { a = min(a, b); }
template <typename T> void ckmax(T &a, const T &b) { a = max(a, b); }

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());

namespace __input {
template <typename T1, typename T2>
istream &operator>>(istream &i, pair<T1, T2> &p) {
  i >> p.first >> p.second;
  return i;
}
template <typename T, size_t N>
istream &operator>>(istream &i, array<T, N> &v) {
  for (auto &e : v) {
    i >> e;
  }
  return i;
}
template <typename T> istream &operator>>(istream &i, vector<T> &v) {
  for (auto &e : v) {
    i >> e;
  }
  return i;
}
} // namespace __input
using namespace __input;

namespace __output {
template <typename T1, typename T2>
ostream &operator<<(ostream &o, const pair<T1, T2> &t) {
  return o << "(" << t.first << ", " << t.second << ")";
}
template <typename T, size_t N>
ostream &operator<<(ostream &o, const array<T, N> &a) {
  o << "[";
  for (int i = 0; i < N; i++) {
    if (i)
      o << ", ";
    o << a[i];
  }
  return o << "]";
}
template <typename T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (int i = 0; i < sz(v); i++) {
    if (i)
      o << ", ";
    o << v[i];
  }
  return o << "]";
}
} // namespace __output
using namespace __output;

template <int MOD> struct modnum {
  int v;
  modnum() : v(0) {}
  modnum(ll _v) : v(_v % MOD) {
    if (v < 0)
      v += MOD;
  }
  explicit operator int() const { return v; }
  friend istream &operator>>(istream &i, modnum &n) {
    ll v;
    i >> v;
    n = modnum(v);
    return i;
  }
  friend ostream &operator<<(ostream &o, const modnum &n) { return o << n.v; }

  friend bool operator==(const modnum &a, const modnum &b) {
    return a.v == b.v;
  }
  friend bool operator!=(const modnum &a, const modnum &b) {
    return a.v != b.v;
  }

  modnum &operator+=(const modnum &o) {
    v += o.v;
    if (v >= MOD)
      v -= MOD;
    return *this;
  }
  modnum &operator-=(const modnum &o) {
    v -= o.v;
    if (v < 0)
      v += MOD;
    return *this;
  }
  modnum &operator*=(const modnum &o) {
    v = int(ll(v) * ll(o.v) % MOD);
    return *this;
  }
  modnum operator-() {
    modnum res;
    if (v)
      res.v = MOD - v;
    return res;
  }
  friend modnum operator+(const modnum &a, const modnum &b) {
    return modnum(a) += b;
  }
  friend modnum operator-(const modnum &a, const modnum &b) {
    return modnum(a) -= b;
  }
  friend modnum operator*(const modnum &a, const modnum &b) {
    return modnum(a) *= b;
  }

  modnum pow(ll e) const {
    if (e == 0)
      return 1;
    if (e & 1)
      return *this * this->pow(e - 1);
    return (*this * *this).pow(e / 2);
  }

  modnum inv() const {
    int g = MOD, x = 0, y = 1;
    for (int r = v; r != 0;) {
      int q = g / r;
      g %= r;
      swap(g, r);
      x -= q * y;
      swap(x, y);
    }

    assert(g == 1);
    assert(y == MOD || y == -MOD);
    return x < 0 ? x + MOD : x;
  }
  modnum &operator/=(const modnum &o) { return (*this) *= o.inv(); }
  friend modnum operator/(const modnum &a, const modnum &b) {
    return modnum(a) /= modnum(b);
  }

  static int totient() {
    int tot = MOD, tmp = MOD;
    for (int p = 2; p * p <= tmp; p++)
      if (tmp % p == 0) {
        tot = tot / p * (p - 1);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot = tot / tmp * (tmp - 1);
    return tot;
  }

  static int primitive_root() {
    if (MOD == 1)
      return 0;
    if (MOD == 2)
      return 1;

    int tot = totient(), tmp = tot;
    vi tot_pr;
    for (int p = 2; p * p <= tmp; p++)
      if (tot % p == 0) {
        tot_pr.push_back(p);
        while (tmp % p == 0)
          tmp /= p;
      }
    if (tmp > 1)
      tot_pr.push_back(tmp);

    for (int r = 2; r < MOD; r++)
      if (__gcd(r, MOD) == 1) {
        bool root = true;
        for (int p : tot_pr)
          root &= modnum(r).pow(tot / p) != 1;
        if (root)
          return r;
      }
    assert(false);
  }

  static modnum generator() {
    static modnum g = primitive_root();
    return g;
  }
  static int discrete_log(modnum v) {
    static const int M = ceil(sqrt(MOD));
    static unordered_map<int, int> table;
    if (table.empty()) {
      modnum e = 1;
      for (int i = 0; i < M; i++) {
        table[e.v] = i;
        e *= generator();
      }
    }
    static modnum f = generator().pow(totient() - M);

    for (int i = 0; i < M; i++) {
      if (table.count(v.v))
        return table[v.v] + i * M;
      v *= f;
    }
    assert(false);
  }

  static modnum fact(int n) {
    static vector<modnum<MOD>> fact = {1};
    for (assert(n >= 0); fact.size() <= n;)
      fact.push_back(fact.back() * fact.size());
    return fact[n];
  }

  static modnum finv(int n) {
    static vector<modnum<MOD>> finv = {1};
    for (assert(n >= 0); finv.size() <= n;)
      finv.push_back(finv.back() / finv.size());
    return finv[n];
  }

  static modnum ncr(int n, int r) {
    if (r < 0 || n < r)
      return 0;
    return fact(n) * finv(r) * finv(n - r);
  }
};
using mn = modnum<int(1e9 + 7)>;
using vmn = vector<mn>;

int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0), cout.tie(0);

  int N, K;
  cin >> N >> K;

  if (N == 1) {
    cout << 1 << endl;
    return 0;
  }

  vi bnd;
  for (int i = 1; i * i <= N; i++) {
    bnd.pb(i);
    bnd.pb(N / i - 1);
    bnd.pb(N / i);
    bnd.pb(N / i + 1);
  }
  sort(all(bnd));
  bnd.erase(unique(all(bnd)), bnd.end());

  vi uniq{bnd[0]}, divs{N};
  FOR(i, 1, sz(bnd)) {
    uniq.pb(bnd[i]);
    divs.pb(N / bnd[i]);
  }

  int U = sz(uniq);
  F0R(i, U - 1) {
    assert(N / uniq[i] == divs[i]);
    assert(N / uniq[i] == N / (uniq[i + 1] - 1));
  }

  vi canp(U - 1), elts(U - 1);
  F0R(j, U - 1) {
    canp[j] = j ? canp[j - 1] : U - 2;
    while (canp[j] > 0 && (bnd[j + 1] - 1) * (bnd[canp[j] + 1] - 1) > N)
      canp[j]--;
    elts[j] = bnd[j + 1] - bnd[j];
  }

  vmn dp(U - 1, 1);

  F0R(i, K) {
    vmn upd(U - 1, 0);
    F0R(j, sz(upd)) { upd[j] = elts[j] * dp[canp[j]]; }
    F0R(j, sz(upd) - 1)
    upd[j + 1] += upd[j];
    swap(dp, upd);
  }

  cout << dp.back() << endl;

  return 0;
}