BZOJ 5215: [Lydsy2017省队十连测]商店购物
裸题
注意+特判
#include<cstdio> using namespace std; const int mod=1e9+7; int F[1000005],mi[10000005],ni[10000005],G[1000005]; int pow(int a,int b){ int ans=1; while (b){ if (b&1) ans=1ll*ans*a%mod; a=1ll*a*a%mod; b=b>>1; } return ans; } int C(int n,int m){ if (n<m) return 0; return 1ll*mi[n]*ni[m]%mod*ni[n-m]%mod; } int main(){ int n,m,k; scanf("%d%d%d",&n,&m,&k); mi[0]=ni[0]=1; for (int i=1; i<=n+k; i++) mi[i]=1ll*mi[i-1]*i%mod; ni[n+k]=pow(mi[n+k],mod-2); for (int i=n+k-1; i>=1; i--) ni[i]=1ll*ni[i+1]*(i+1)%mod; n-=m; F[0]=1; int tot=0; for (int i=1; i<=m; i++){ int x; scanf("%d",&x); tot+=x; for (int j=0; j<=m*300; j++) G[j]=F[j]; for (int j=1; j<=m*300; j++) (G[j]+=G[j-1])%=mod; for (int j=0; j<=m*300; j++){ int l=j-x-1; F[j]=G[j]; if (l>=0) F[j]-=G[l]; (F[j]+=mod)%=mod; } } int ans=0; if (!n){ if (k<=tot) ans=F[k]; else ans=0; } else{ for (int i=0; i<=m*300; i++){ int K=k-i; if (K<0) break; (ans+=1ll*F[i]*C(K+n-1,n-1)%mod)%=mod; } } printf("%d\n",ans); return 0; }