Problem p02992 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
#define SELECTER(_1, _2, _3, SELECT, ...) SELECT
#define REP1(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define REP2(i, a, b) for (int(i) = (a); (i) < (b); (i)++)
#define REP(...) SELECTER(__VA_ARGS__, REP2, REP1, )(__VA_ARGS__)
#define MOD 1000000007

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  for (size_t i = 0; i < v.size(); i++)
    os << v[i] << (i + 1 == v.size() ? "" : ", ");
  os << "}";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << "{" << p.first << ", " << p.second << "}";
}

template <class X> class SegmentTree {
  int n;
  vector<X> dat;
  X identity;

  X query_sub(int a, int b, int i, int l, int r) {
    if (r <= a || b <= l)
      return identity;
    if (a <= l && r <= b)
      return dat[i];
    else {
      X vl = query_sub(a, b, i * 2 + 1, l, (l + r) / 2);
      X vr = query_sub(a, b, i * 2 + 2, (l + r) / 2, r);
      return op(vl, vr);
    }
  }

  X get_identity() {
    return 0; // Range Sum Query
  }
  X op(X x, X y) {
    return (x + y) % MOD; // Range Sum Query
  }

public:
  SegmentTree(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;

    identity = get_identity();
    dat = vector<X>(2 * n - 1, identity);
  }
  void update(int i, X x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2;
      dat[i] = op(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }
  // [a, b)
  X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
  X at(int i) { return dat[i + n - 1]; }
};

template <class X> class FenwickTree {
  int n;
  vector<X> a;

public:
  FenwickTree(int n) : n(n), a(n + 1, 0) {}
  X get(int i) {
    X sm = 0;
    for (; i > 0; i -= i & -i)
      sm = (sm + a[i]) % MOD;
    return sm;
  }
  void add(int i, X x) {
    for (; i <= n; i += i & -i)
      a[i] = (a[i] + x) % MOD;
  }
  X at(int i) { return (MOD + get(i) - get(i - 1)) % MOD; }
};

int main() {
  int N, K;
  cin >> N >> K;

  vector<int> div;
  set<int> st;
  for (int i = 1; i <= 2 * sqrt(N); i++) {
    st.insert(N / i);
    st.insert(i);
  }
  for (auto x : st)
    div.push_back(x);

  // SegmentTree<long long> seg[2] = {
  //     SegmentTree<long long>(div.size()+1),
  //     SegmentTree<long long>(div.size()+1),
  // };
  FenwickTree<long long> seg[2] = {
      FenwickTree<long long>(div.size() + 10),
      FenwickTree<long long>(div.size() + 10),
  };

  map<int, int> mp;
  for (int i = 0; i < div.size(); i++)
    mp[div[i]] = i;
  vector<vector<long long>> dp(K, vector<long long>(div.size()));
  // seg[0].update(0, 1);
  seg[0].add(1, 1);
  for (int i = 1; i < div.size(); i++)
    // seg[0].update(i, div[i]-div[i-1]);
    seg[0].add(i + 1, div[i] - div[i - 1]);

  for (int i = 1; i < K; i++) {
    for (int j = 0; j < div.size(); j++) {
      int x = div[j];
      int y = N / x;
      long long fac = 1;
      if (j != 0)
        fac = div[j] - div[j - 1];
      // long long tmp = seg[(i-1)%2].query(0, mp[y]+1);
      long long tmp = seg[(i - 1) % 2].get(mp[y] + 1);
      tmp = (tmp * fac) % MOD;
      // seg[i%2].update(j, tmp);
      seg[i % 2].add(j + 1, ((MOD - seg[i % 2].at(j + 1)) % MOD + tmp) % MOD);
    }
  }
  // long long ans = seg[(K-1)%2].query(0, div.size());
  long long ans = seg[(K - 1) % 2].get(div.size());
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
#define SELECTER(_1, _2, _3, SELECT, ...) SELECT
#define REP1(i, n) for (int(i) = 0; (i) < (n); (i)++)
#define REP2(i, a, b) for (int(i) = (a); (i) < (b); (i)++)
#define REP(...) SELECTER(__VA_ARGS__, REP2, REP1, )(__VA_ARGS__)
#define MOD 1000000007

template <class T> ostream &operator<<(ostream &os, const vector<T> &v) {
  os << "{";
  for (size_t i = 0; i < v.size(); i++)
    os << v[i] << (i + 1 == v.size() ? "" : ", ");
  os << "}";
  return os;
}
template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << "{" << p.first << ", " << p.second << "}";
}

template <class X> class SegmentTree {
  int n;
  vector<X> dat;
  X identity;

  X query_sub(int a, int b, int i, int l, int r) {
    if (r <= a || b <= l)
      return identity;
    if (a <= l && r <= b)
      return dat[i];
    else {
      X vl = query_sub(a, b, i * 2 + 1, l, (l + r) / 2);
      X vr = query_sub(a, b, i * 2 + 2, (l + r) / 2, r);
      return op(vl, vr);
    }
  }

  X get_identity() {
    return 0; // Range Sum Query
  }
  X op(X x, X y) {
    return (x + y) % MOD; // Range Sum Query
  }

public:
  SegmentTree(int n_) {
    n = 1;
    while (n < n_)
      n *= 2;

    identity = get_identity();
    dat = vector<X>(2 * n - 1, identity);
  }
  void update(int i, X x) {
    i += n - 1;
    dat[i] = x;
    while (i > 0) {
      i = (i - 1) / 2;
      dat[i] = op(dat[i * 2 + 1], dat[i * 2 + 2]);
    }
  }
  // [a, b)
  X query(int a, int b) { return query_sub(a, b, 0, 0, n); }
  X at(int i) { return dat[i + n - 1]; }
};

template <class X> class FenwickTree {
  int n;
  vector<X> a;

public:
  FenwickTree(int n) : n(n), a(n + 1, 0) {}
  X get(int i) {
    X sm = 0;
    for (; i > 0; i -= i & -i)
      sm = (sm + a[i]) % MOD;
    return sm;
  }
  void add(int i, X x) {
    for (; i <= n; i += i & -i)
      a[i] = (a[i] + x) % MOD;
  }
  X at(int i) { return (MOD + get(i) - get(i - 1)) % MOD; }
};

int main() {
  int N, K;
  cin >> N >> K;
  if (N == 1) {
    cout << 1 << endl;
    return 0;
  }

  vector<int> div;
  set<int> st;
  for (int i = 1; i <= 2 * sqrt(N); i++) {
    st.insert(N / i);
    st.insert(i);
  }
  for (auto x : st)
    div.push_back(x);

  // SegmentTree<long long> seg[2] = {
  //     SegmentTree<long long>(div.size()+1),
  //     SegmentTree<long long>(div.size()+1),
  // };
  FenwickTree<long long> seg[2] = {
      FenwickTree<long long>(div.size() + 10),
      FenwickTree<long long>(div.size() + 10),
  };

  map<int, int> mp;
  for (int i = 0; i < div.size(); i++)
    mp[div[i]] = i;
  vector<vector<long long>> dp(K, vector<long long>(div.size()));
  // seg[0].update(0, 1);
  seg[0].add(1, 1);
  for (int i = 1; i < div.size(); i++)
    // seg[0].update(i, div[i]-div[i-1]);
    seg[0].add(i + 1, div[i] - div[i - 1]);

  for (int i = 1; i < K; i++) {
    for (int j = 0; j < div.size(); j++) {
      int x = div[j];
      int y = N / x;
      long long fac = 1;
      if (j != 0)
        fac = div[j] - div[j - 1];
      // long long tmp = seg[(i-1)%2].query(0, mp[y]+1);
      long long tmp = seg[(i - 1) % 2].get(mp[y] + 1);
      tmp = (tmp * fac) % MOD;
      // seg[i%2].update(j, tmp);
      seg[i % 2].add(j + 1, ((MOD - seg[i % 2].at(j + 1)) % MOD + tmp) % MOD);
    }
  }
  // long long ans = seg[(K-1)%2].query(0, div.size());
  long long ans = seg[(K - 1) % 2].get(div.size());
  cout << ans << endl;
  return 0;
}