Problem:
Problem F: Sum of Numbers
Problem
a
以上
b
以下の整数が書かれたカードがそれぞれ
c
枚ずつあります。
これら
c(b-a+1)
枚のカードの中から
d
枚のカードを選択したとき、それらのカードに書かれている整数の合計が
e
になる場合の数を1,000,000,007で割った余りを求めてください。
Input
入力は以下の形式で与えられる。
a
b
c
d
e
1行目に、5つの整数
a
b
c
d
e
が空白区切りで与えられる。
Constraints
入力は以下の制約を満たす。
1 ≤
a
≤ 1000
a
≤
b
≤ 1000
1 ≤
c
≤ 100
1 ≤
d
≤ 1000
c
≤
d
≤
c(b-a+1)
1 ≤
e
≤ 20000
Output
場合の数を1,000,000,007で割った余りを出力せよ。
Sample Input1
2 5 3 3 11
Sample Output1
3
{2,2,2,3,3,3,4,4,4,5,5,5}の中から3枚選び合計が11になるのは、
{2,4,5},{3,3,5},{3,4,4}の３通りである。
Sample Input2
1 2 3 4 100
Sample Output2
0
{1,1,1,2,2,2}の中から4枚選び合計が100になるのは0通りである。

Submitted solutions:

code_snippet: // AOJ #1556 Sum of Numbers
// 2025.4.29

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
const int MOD = 1000000007;

const int M_SIZE = 108;
const int J_SIZE = 21600;
ll dp[M_SIZE][J_SIZE];
ll dp1_arr[M_SIZE][J_SIZE];
ll dp2_arr[M_SIZE][J_SIZE];

int main(){
    int a, b, c, d, e;
    cin >> a >> b >> c >> d >> e;
    b -= a;
    e -= (ll)a * d;
    if(e < 0){
        cout << 0 << endl;
        return 0;
    }

    dp[0][0] = dp1_arr[0][0] = dp2_arr[0][0] = 1;
    for(int i = 0; i <= d; i++){
        for(int j = 0; j <= e; j++){
            if(i == 0 && j == 0) continue;
            ll val = 0;

            int l = max(0, i - j);
            int r = min(c, i);
            if(l <= r){
                int i1 = i - l;
                int j1 = j - (i - l);
                if(j1 >= 0) val += dp1_arr[i1 % M_SIZE][j1];

                int i2 = i - (r + 1);
                int j2 = j - (i - (r + 1));
                if(r + 1 <= i && j2 >= 0) val -= dp1_arr[i2 % M_SIZE][j2];
            }

            int l2 = 1;
            int r2 = min(c, i);
            r2 = min(r2, j / (b + 1));
            if(l2 <= r2){
                int i3 = i - l2;
                int j3 = j - (b + 1) * l2;
                if(j3 >= 0) val -= dp2_arr[i3 % M_SIZE][j3];

                int i4 = i - (r2 + 1);
                int j4 = j - (b + 1) * (r2 + 1);
                if(r2 + 1 <= i && j4 >= 0) val += dp2_arr[i4 % M_SIZE][j4];
            }
            val %= MOD;
            if(val < 0) val += MOD;
            dp[i % M_SIZE][j] = val;

            ll v1 = val;
            if(i > 0 && j + 1 <= e) v1 = (v1 + dp1_arr[(i - 1) % M_SIZE][j + 1]) % MOD;
            dp1_arr[i % M_SIZE][j] = v1;

            ll v2 = val;
            if(i > 0 && j - (b + 1) >= 0) v2 = (v2 + dp2_arr[(i - 1) % M_SIZE][j - (b + 1)]) % MOD;
            dp2_arr[i % M_SIZE][j] = v2;
        }
    }
    cout << dp[d % M_SIZE][e] << endl;
    return 0;
}
accuracy: 1
time_ms: 190
memory_kb: 57668
final_rank: 1

code_snippet: //Let's join Kaede Takagaki Fan Club !!
#pragma GCC optimize("Ofast")
#pragma GCC optimize("unroll-loops")
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <cassert>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <stack>
#include <functional>
#include <iostream>
#include <map>
#include <set>
#include <unordered_map>
#include <unordered_set>
#include <cassert>
#include <iomanip>
#include <chrono>
#include <random>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <bitset>
//#include <atcoder/segtree>
using namespace std;
//using namespace atcoder;
//#define int long long
//#define L __int128
typedef long long ll;
typedef pair<int,int> P;
typedef pair<int,P> P1;
typedef pair<P,P> P2;
#define pu push
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define eps 1e-7
#define INF 1000000000
#define a first
#define b second
#define fi first
#define sc second
#define rng(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define rep(i,x) for(int i=0;i<x;i++)
#define repn(i,x) for(int i=1;i<=x;i++)
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
#define all(x) x.begin(),x.end()
#define si(x) int(x.size())
 
#ifdef LOCAL
#define dmp(x) cerr<<__LINE__<<" "<<#x<<" "<<x<<endl
#else
#define dmp(x) void(0)
#endif
 
template<class t,class u> bool chmax(t&a,u b){if(a<b){a=b;return true;}else return false;}
template<class t,class u> bool chmin(t&a,u b){if(b<a){a=b;return true;}else return false;}
 
template<class t> using vc=vector<t>;
 
template<class t,class u>
ostream& operator<<(ostream& os,const pair<t,u>& p){
	return os<<"{"<<p.fi<<","<<p.sc<<"}";
}
 
template<class t> ostream& operator<<(ostream& os,const vc<t>& v){
	os<<"{";
	for(auto e:v)os<<e<<",";
	return os<<"}";
}
 
template<class T>
void g(T &a){
	cin >> a;
}
template<class T>
void o(const T &a,bool space=false){
	cout << a << (space?' ':'\n');
}
//ios::sync_with_stdio(false);
//const ll mod = 998244353;
const ll mod = 1000000007;
mt19937_64 mt(chrono::steady_clock::now().time_since_epoch().count());
template<class T>
void add(T&a,T b){
	a+=b;
	if(a >= mod) a-=mod;
}
ll modpow(ll x,ll n){
	ll res=1;
	while(n>0){
		if(n&1) res=res*x%mod;
		x=x*x%mod;
		n>>=1;
	}
	return res;
}
#define _sz 400005
ll F[_sz],R[_sz];
void make(){
	F[0] = 1;
	for(int i=1;i<_sz;i++) F[i] = F[i-1]*i%mod;
	R[_sz-1] = modpow(F[_sz-1], mod-2);
	for(int i=_sz-2;i>=0;i--) R[i] = R[i+1] * (i+1) % mod;
}
ll C(int a,int b){
	if(b < 0 || a < b) return 0;
	return F[a]*R[b]%mod*R[a-b]%mod;
}
int a, b, c, d, e, dp[1005][20005], pre[1005][20005];
void solve(){
	cin >> a >> b >> c >> d >> e;
	dp[0][0] = 1;
	for(int use=b;use>=a;use--){
		for(int cur=0;cur<=min(d, e/use);cur++){
			for(int sum=cur*use;sum<=e;sum++){
				pre[cur][sum] = dp[cur][sum];
				if(cur >= 1 and sum >= use){
				    pre[cur][sum] += pre[cur-1][sum-use];
				    if(pre[cur][sum] >= mod) pre[cur][sum] -= mod;
				}
			}
		}
		for(int cur=min(d, e/use);cur>=1;cur--){
			for(int sum=e;sum>=cur*use;sum--){
				//dp[cur][sum]
				dp[cur][sum] = pre[cur][sum];
				if(cur >= c+1 and sum >= (c+1)*use){
				    dp[cur][sum] += mod-pre[cur-c-1][sum-(c+1)*use];
				}
				if(dp[cur][sum]>=mod)dp[cur][sum]-=mod;
			}
		}
	}
	o(dp[d][e]);
}
signed main(){
	cin.tie(0);
	ios::sync_with_stdio(0);
	cout<<fixed<<setprecision(20);
	int t; t = 1; //cin >> t;
	while(t--) solve();
}
accuracy: 1
time_ms: 1490
memory_kb: 161144
final_rank: 3

code_snippet: #include<iostream>
#include<algorithm>

using namespace std;

#define MOD 1000000007
#define M 108
typedef long long Int;

int a, b, c, d, e;
Int dp[108][21600];
Int dp1[108][21600];
Int dp2[108][21600];
int main(){
  cin >> a >> b >> c >> d >> e;
  b -= a;
  e -= a*d;
  dp[0][0] = 1;
  dp1[0][0] = 1;
  dp2[0][0] = 1;
  for(int i = 0;i <= d;i++){
    for(int j = 0;j < 21500;j++){
      if(i == 0 && j == 0)continue;
      dp[i%M][j] = 0;    
      int l = max(0, i - j);
      int r = min(c, i);
	  if(l <= r){
	      if(i-l>=0 && j - (i-l) >= 0)dp[i%M][j] += dp1[(i-l)%M][j-(i-l)];
	      if(i-(r+1) >= 0 && j-(i-(r+1)) >= 0)dp[i%M][j] -= dp1[(i-(r+1))%M][j-(i-(r+1))];
	  }
/*      for(int k = l;k <= r;k++){
	dp[i][j] += dp[i-k][j-(i-k)];
	} */
      l = 1;
      r = min(c, i);
      r = min(r, j / (b+1));
      if(l <= r){
	      if(i-l >= 0 && j-(b+1)*l >= 0)dp[i%M][j] -= dp2[(i-l)%M][j-(b+1)*l];
	      if(i-(r+1) >= 0 && j-(b+1)*(r+1) >= 0)dp[i%M][j] += dp2[(i-(r+1))%M][j-(b+1)*(r+1)];
	  }
/*      for(int k = l;k <= r;k++){
	dp[i][j] -= dp[i-k][j-(b+1)*k];
	}*/
      dp[i%M][j] %= MOD;
      if(dp[i%M][j] < 0)dp[i%M][j] += MOD;
      dp1[i%M][j] = dp2[i%M][j] = dp[i%M][j];
      if(i)(dp1[i%M][j] += dp1[(i-1)%M][j+1])%=MOD;
      if(i && j-(b+1)>=0)(dp2[i%M][j] += dp2[(i-1)%M][j-(b+1)])%=MOD;
    }
  }
  cout << dp[d%M][e] << endl;
  return 0;
}
accuracy: 1
time_ms: 360
memory_kb: 55836
final_rank: 2

code_snippet: #include<iostream>
#include<algorithm>

using namespace std;

#define MOD 1000000007
#define M 108
typedef long long Int;

int a, b, c, d, e;
Int dp[108][21600];
Int dp1[108][21600];
Int dp2[108][21600];
int main(){
  cin >> a >> b >> c >> d >> e;
  b -= a;
  e -= a*d;
  dp[0][0] = 1;
  dp1[0][0] = 1;
  dp2[0][0] = 1;
  for(int i = 0;i <= d;i++){
    for(int j = 0;j < 21500;j++){
      if(i == 0 && j == 0)continue;
      dp[i%M][j] = 0;    
      int l = max(0, i - j);
      int r = min(c, i);
/*      if(i-l>=0 && j - (i-l) >= 0)dp[i%M][j] += dp1[(i-l)%M][j-(i-l)];
      if(i-(r+1) >= 0 && j-(i-(r+1)) >= 0)dp[i%M][j] -= dp1[(i-(r+1))%M][j-(i-(r+1))];*/
      for(int k = l;k <= r;k++){
	dp[i][j] += dp[i-k][j-(i-k)];
	}
      l = 1;
      r = min(c, i);
      r = min(r, j / (b+1));
      
/*      if(i-l >= 0 && j-(b+1)*l >= 0)dp[i%M][j] -= dp2[(i-l)%M][j-(b+1)*l];
      if(i-(r+1) >= 0 && j-(b+1)*(r+1) >= 0)dp[i%M][j] += dp2[(i-(r+1))%M][j-(b+1)*(r+1)];*/
      for(int k = l;k <= r;k++){
	dp[i][j] -= dp[i-k][j-(b+1)*k];
	}
      dp[i%M][j] %= MOD;
      if(dp[i%M][j] < 0)dp[i%M][j] += MOD;
      dp1[i%M][j] = dp2[i%M][j] = dp[i%M][j];
      if(i)(dp1[i%M][j] += dp1[(i-1)%M][j+1])%=MOD;
      if(i && j-(b+1)>=0)(dp2[i%M][j] += dp2[(i-1)%M][j-(b+1)])%=MOD;
    }
  }
  cout << dp[d%M][e] << endl;
  return 0;
}
accuracy: 0.25
time_ms: 610
memory_kb: 55768
final_rank: 4