Language: C++

#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>

using ll = long long;

using namespace std;

#include <mutex>

#define MOD (long)(1e9 + 7)
#define MAX 1000000  // 階乗をいくつまで計算するか

class modlong {
    long val;
    static const long mod = MOD;
    static long *invs, *facts, *finvs;
    static once_flag flag;

    // 階乗, 逆元, 階乗の逆元をMAXまで求める
    static void initModlong() {
        invs[1] = 
        facts[0] = facts[1] =
        finvs[0] = finvs[1] = 1;
        for (int i=2; i<=MAX; i++) {
            invs[i]  = -invs[MOD % i] * (MOD / i) % MOD;
            facts[i] = facts[i - 1] * i % MOD;
            finvs[i] = finvs[i - 1] * invs[i] % MOD;
        }
    }

public:
    // 初期化 値を引数に与えなかった場合はval=0としておく
    modlong(long init = 0) : val(init) {
        call_once(flag, initModlong);
        if (val < 0 || val >= mod) val %= mod;
        if (val < 0) val += mod;   // 0以上であることを保証
    }

    // longへのキャスト operator long()で定義すると modlong +
    // longとかができなくなる
    constexpr long tol() { return this->val; }

    // 代入
    void operator=(const modlong &r) { this->val = r.val; }
    void operator=(const long &r) { *this = modlong(r); }

    //比較
    bool operator<(const modlong &r) { return this->val < r.val; }
    bool operator>(const modlong &r) { return this->val > r.val; }
    bool operator==(const modlong &r) { return this->val == r.val; }
    bool operator!=(const modlong &r) { return !(*this == r); }
    bool operator<=(const modlong &r) { return !(*this > r); }
    bool operator>=(const modlong &r) { return !(*this < r); }

    // 足し算; 符号反転; 引き算
    modlong operator+(const modlong &r) {
        long ans = this->val + r.val;
        if (ans >= mod) ans -= mod;
        return modlong(ans);
    }
    modlong operator-() {
        long ans = mod - this->val;
        return modlong(ans);
    }
    modlong operator-(const modlong &r) {
        modlong rr = r;
        return *this + (-rr);
    }

    //かけ算; 逆元; わり算
    modlong operator*(const modlong &r) {
        long ans = this->val * r.val;
        return modlong(ans);
    }
    modlong inv() {
        assert(*this != 0);
        if (*this == 1) return modlong(1);

        modlong p, q = *this, m(0), n(1), r, c;
        p.val = mod;  // p=modとかくとp.val=mod%mod=0となってしまう
        while (q > MAX) {
            r = p.val %
                q.val;  // r.val=p.val / q.val
                        // とかくよりもこのほうが代入時に%modされるので安全
            c = m.val - n.val * (p.val / q.val);
            p = q, q = r, m = n, n = c;
        }
        return n * invs[q.val];
    }
    modlong operator/(const modlong &r) {
        modlong rr = r;
        return *this * rr.inv();
    }

    // ++ -- 前付きと後ろ付き
    void operator++() { ++this->val; }
    void operator++(int a) {
        a = 0;
        this->val++;
    }  // a使ってなくねっていうwarningをsilenceするためにaをいじってる
    void operator--() { --this->val; }
    void operator--(int a) {
        a = 0;
        this->val--;
    }

    // 四則演算&代入
    void operator+=(const modlong &r) { *this = *this + r; }
    void operator-=(const modlong &r) { *this = *this - r; }
    void operator*=(const modlong &r) { *this = *this * r; }
    void operator/=(const modlong &r) { *this = *this / r; }

    // べき乗
    modlong pow(long n) {
        if (n < 0)
            return inv().pow(-n);  // 逆元の-n乗
        else if (n == 0)
            return modlong(1);

        modlong half = pow(n / 2);
        if (n % 2)
            return *this * half * half;
        else
            return half * half;
    }
    modlong pow(modlong n) { return pow(n.val); }

    // コンビネーション
    modlong comb(modlong _k) {
        assert(this->val <= MAX);
        const long n = this->val, k = _k.val;
        if (k < 0 || k > n) return 0;
        if (k == 0 || k == n) return 1;
        return modlong(facts[n]) * finvs[k] * finvs[n - k];
    }

    // 階乗
    modlong fact() { 
        assert(this->val <= MAX);
        return modlong(facts[this->val]);
    }

    friend ostream &operator<<(ostream &os, const modlong &out);
    friend istream &operator>>(istream &is, modlong &out);
};

// cout、cerr、cin用の演算子たち
ostream &operator<<(ostream &os, const modlong &out) {
    os << out.val;
    return os;
}
istream &operator>>(istream &is, modlong &in) {
    long inl;
    is >> inl;
    in.val = inl % MOD;
    return is;
}

// static変数たち
long *modlong::invs  = new long[MAX+1],
     *modlong::facts = new long[MAX+1],
     *modlong::finvs = new long[MAX+1];
once_flag modlong::flag;

//////      階乗を全て求める -> 二項係数を求める
// コンビネーション
inline modlong modComb(long n, long k) {
    return modlong(n).comb(k);
}
// 階乗
inline modlong modFact(long n) {
    return modlong(n).fact();
}

modlong dp[1002][1001] = {{0}};

int main() {
    int n, a, b, c, d;
    cin >> n >> a >> b >> c >> d;
    dp[a][n] = 1;
    for (int i=a; i<=b; i++) {
        for (int j=0; j<=n; j++) {
            // cerr << i << ' ' << j << ' ' << dp[i][j] << '\n';
            dp[i+1][j] += dp[i][j];
            for (int k=c; k<=d && i*k <= j; k++) {
                dp[i+1][j-i*k] += dp[i][j] * modFact(j) / (modFact(j - i*k) * modFact(i).pow(k) * modFact(k));
            }
        }
    }
    cout << dp[b+1][0] << '\n';
    return 0;
}


Compiler output:
a.cc: In member function 'modlong modlong::inv()':
a.cc:79:9: error: 'assert' was not declared in this scope
   79 |         assert(*this != 0);
      |         ^~~~~~
a.cc:12:1: note: 'assert' is defined in header '<cassert>'; this is probably fixable by adding '#include <cassert>'
   11 | #include <mutex>
  +++ |+#include <cassert>
   12 | 
a.cc: In member function 'modlong modlong::comb(modlong)':
a.cc:133:9: error: 'assert' was not declared in this scope
  133 |         assert(this->val <= MAX);
      |         ^~~~~~
a.cc:133:9: note: 'assert' is defined in header '<cassert>'; this is probably fixable by adding '#include <cassert>'
a.cc: In member function 'modlong modlong::fact()':
a.cc:142:9: error: 'assert' was not declared in this scope
  142 |         assert(this->val <= MAX);
      |         ^~~~~~
a.cc:142:9: note: 'assert' is defined in header '<cassert>'; this is probably fixable by adding '#include <cassert>'