题目大意
【50%】n, k<=1000
【100%解法1】
以上抄自 WerKeyTom_FTD 给的笔记,我还没学会
【100%解法2】
代码
//解法2
#include<cmath>
#include<cstdio>
#include<algorithm>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
typedef long long LL;
const int maxn=1e5+5, maxsqrtk=448;
const LL mo=1e9+7;
int n,k;
LL fac[2*maxn],ny[2*maxn];
LL mi(LL x,LL y)
{
LL re=1;
for(; y; y>>=1, x=x*x%mo) if (y&1) re=re*x%mo;
return re;
}
void C_Pre(int n)
{
fac[0]=ny[0]=1;
fo(i,1,n) fac[i]=fac[i-1]*i%mo;
ny[n]=mi(fac[n],mo-2);
fd(i,n-1,1) ny[i]=ny[i+1]*(i+1)%mo;
}
LL C(int n,int m) {return fac[n]*ny[m]%mo*ny[n-m]%mo;}
LL f[maxsqrtk+2][maxn],g[maxn];
int main()
{
scanf("%d %d",&n,&k);
C_Pre(2*max(n,k));
f[0][0]=g[0]=1;
fo(i,1,maxsqrtk)
fo(j,1,k)
{
if (j>=i) (f[i][j]-=f[i-1][j-i])%=mo; // 新加一个大小为1的物品
if (j>=i) (f[i][j]+=f[i][j-i])%=mo; // 全体+1
if (j>=n+1) (f[i][j]+=f[i-1][j-(n+1)])%=mo;
(g[j]+=f[i][j])%=mo;
}
LL ans=0;
fo(i,0,k) (ans+=g[i]*C(k-i+n-1,n-1))%=mo;
printf("%lld\n",(ans+mo)%mo);
}