Problem p02932 (C++)

Buggy submission (status: Runtime Error):
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i, s, e) for (i64(i) = (s); (i) < (e); (i)++)
#define all(x) x.begin(), x.end()
#define let auto const

template <typename... Types> struct dynarr : std::vector<Types...> {
  using std::vector<Types...>::vector;
  using size_type = typename std::vector<Types...>::size_type;
  auto &&operator[](size_type i) { return this->at(i); }
  auto &&operator[](size_type i) const { return this->at(i); }
};

template <i64 M> struct modint {
  i64 a;
  constexpr modint(const i64 x = 0) noexcept : a((x % M + M) % M) {}
  constexpr i64 value() const noexcept { return a; }
  constexpr modint &operator+=(const modint r) noexcept {
    a += r.a;
    if (a >= M)
      a -= M;
    return *this;
  }
  constexpr modint &operator=(const i64 r) {
    a = (r % M + M) % M;
    return *this;
  }
  constexpr modint &operator-=(const modint r) noexcept {
    a -= r.a;
    if (a < 0)
      a += M;
    return *this;
  }
  constexpr modint &operator*=(const modint r) noexcept {
    a = a * r.a % M;
    return *this;
  }
  constexpr modint &operator/=(modint r) noexcept {
    i64 ex = M - 2;
    while (ex) {
      if (ex & 1) {
        *this *= r;
      }
      r *= r;
      ex >>= 1;
    }
    return *this;
  }

  constexpr modint operator+(const modint r) const {
    return modint(*this) += r;
  }
  constexpr modint operator-(const modint r) const {
    return modint(*this) -= r;
  }
  constexpr modint operator*(const modint r) const {
    return modint(*this) *= r;
  }
  constexpr modint operator/(const modint r) const {
    return modint(*this) /= r;
  }
};

using fp = modint<(i64)(1e9 + 7)>;

const int MAX = 510000;

fp fac[MAX], finv[MAX];

void COMinit() {
  fac[0] = 1;
  for (i64 i = 1; i < MAX; i++) {
    fac[i] = fac[i - 1] * fp(i);
  }
  finv[MAX - 1] = fp(1) / fac[MAX - 1];
  for (i64 i = MAX - 2; i >= 0; i--) {
    finv[i] = finv[i + 1] * fp(i + 1);
  }
}

fp com(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k]);
}

int main() {
  COMinit();
  i64 N, M, L, R;
  cin >> N >> M >> L >> R;
  // (1 - T)^(N - M)

  dynarr<fp> f(R + 1);
  rep(i, 0, R + 1) {
    f[i] = com(N - M, i);
    if (i % 2 == 1)
      f[i] *= fp(-1);
  }

  // T^M * (1 - T)^(N - M)

  dynarr<fp> F(R + 1);
  rep(i, M, R + 1) { F[i] = f[i - M]; }

  // P = sigma(k = 1 ~ inf) { F(T^k) }
  dynarr<fp> P(R + 1);
  for (i64 i = 1; i <= R; i++) {
    for (i64 k = 1; i * k <= R; k++) {
      P[i * k] += F[i];
    }
  }

  // (1 / (1 - T))^(N + 1)

  dynarr<fp> q(R + 1);
  rep(n, 0, R + 1) { q[n] = com(n + (N + 1) - 1, (N + 1) - 1); }

  // (1 - T^M) * (1 / (1 - T))^(N + 1)

  dynarr<fp> Q(R + 1);
  rep(i, 0, R + 1) {
    Q[i] = q[i];
    if (i - M >= 0)
      Q[i] -= q[i - M];
  }

  fp Sr = 0;

  for (i64 i = 0; i <= R; i++) {
    Sr += P[i] * Q[R - i];
  }

  fp Sl = 0;
  L--;
  for (i64 i = 0; i <= L; i++) {
    Sl += P[i] * Q[L - i];
  }

  fp rev = (Sr - Sl) * com(N, M);
  fp al = q[R] - q[L];

  cout << (al - rev).value() << endl;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
#define rep(i, s, e) for (i64(i) = (s); (i) < (e); (i)++)
#define all(x) x.begin(), x.end()
#define let auto const

template <typename... Types> struct dynarr : std::vector<Types...> {
  using std::vector<Types...>::vector;
  using size_type = typename std::vector<Types...>::size_type;
  auto &&operator[](size_type i) { return this->at(i); }
  auto &&operator[](size_type i) const { return this->at(i); }
};

template <i64 M> struct modint {
  i64 a;
  constexpr modint(const i64 x = 0) noexcept : a((x % M + M) % M) {}
  constexpr i64 value() const noexcept { return a; }
  constexpr modint &operator+=(const modint r) noexcept {
    a += r.a;
    if (a >= M)
      a -= M;
    return *this;
  }
  constexpr modint &operator=(const i64 r) {
    a = (r % M + M) % M;
    return *this;
  }
  constexpr modint &operator-=(const modint r) noexcept {
    a -= r.a;
    if (a < 0)
      a += M;
    return *this;
  }
  constexpr modint &operator*=(const modint r) noexcept {
    a = a * r.a % M;
    return *this;
  }
  constexpr modint &operator/=(modint r) noexcept {
    i64 ex = M - 2;
    while (ex) {
      if (ex & 1) {
        *this *= r;
      }
      r *= r;
      ex >>= 1;
    }
    return *this;
  }

  constexpr modint operator+(const modint r) const {
    return modint(*this) += r;
  }
  constexpr modint operator-(const modint r) const {
    return modint(*this) -= r;
  }
  constexpr modint operator*(const modint r) const {
    return modint(*this) *= r;
  }
  constexpr modint operator/(const modint r) const {
    return modint(*this) /= r;
  }
};

using fp = modint<(i64)(1e9 + 7)>;

const int MAX = 606060;

fp fac[MAX], finv[MAX];

void COMinit() {
  fac[0] = 1;
  for (i64 i = 1; i < MAX; i++) {
    fac[i] = fac[i - 1] * fp(i);
  }
  finv[MAX - 1] = fp(1) / fac[MAX - 1];
  for (i64 i = MAX - 2; i >= 0; i--) {
    finv[i] = finv[i + 1] * fp(i + 1);
  }
}

fp com(int n, int k) {
  if (n < k)
    return 0;
  if (n < 0 || k < 0)
    return 0;
  return fac[n] * (finv[k] * finv[n - k]);
}

int main() {
  COMinit();
  i64 N, M, L, R;
  cin >> N >> M >> L >> R;
  // (1 - T)^(N - M)

  dynarr<fp> f(R + 1);
  rep(i, 0, R + 1) {
    f[i] = com(N - M, i);
    if (i % 2 == 1)
      f[i] *= fp(-1);
  }

  // T^M * (1 - T)^(N - M)

  dynarr<fp> F(R + 1);
  rep(i, M, R + 1) { F[i] = f[i - M]; }

  // P = sigma(k = 1 ~ inf) { F(T^k) }
  dynarr<fp> P(R + 1);
  for (i64 i = 1; i <= R; i++) {
    for (i64 k = 1; i * k <= R; k++) {
      P[i * k] += F[i];
    }
  }

  // (1 / (1 - T))^(N + 1)

  dynarr<fp> q(R + 1);
  rep(n, 0, R + 1) { q[n] = com(n + (N + 1) - 1, (N + 1) - 1); }

  // (1 - T^M) * (1 / (1 - T))^(N + 1)

  dynarr<fp> Q(R + 1);
  rep(i, 0, R + 1) {
    Q[i] = q[i];
    if (i - M >= 0)
      Q[i] -= q[i - M];
  }

  fp Sr = 0;

  for (i64 i = 0; i <= R; i++) {
    Sr += P[i] * Q[R - i];
  }

  fp Sl = 0;
  L--;
  for (i64 i = 0; i <= L; i++) {
    Sl += P[i] * Q[L - i];
  }

  fp rev = (Sr - Sl) * com(N, M);
  fp al = q[R] - q[L];

  cout << (al - rev).value() << endl;
}