CF451E Devu and Flowers 解題報告
阿新 • • 發佈:2018-11-11
CF451E Devu and Flowers
題意:
\(Devu\)有\(N\)個盒子,第\(i\)個盒子中有\(c_i\)枝花。同一個盒子內的花顏色相同,不同盒子的花顏色不同。\(Devu\)要從中選出\(M\)枝花,求有多少種方案,對\(10e9+7\)取模。
資料範圍
\(1 \le N \le 20,0 \le M \le 10^{14},0 \le c_i \le 10^{12}\)
其實就是求多重集組合數的模板題。
一些注意點,發現直接求會爆\(long long\),\(lucas\)一下免得爆了
注意\(M\)很大\(N\)很小,所以先把\((M-N)!\)
Code:
#include <cstdio> #define ll long long const ll mod=1e9+7; ll quickpow(ll d,ll k) { ll f=1; while(k) { if(k&1) f=f*d%mod; d=d*d%mod; k>>=1; } return f; } ll cal(ll r,ll l) { ll s=1; for(ll i=r;i>l;i--) (s*=i)%=mod; return s; } ll inv[22]; ll C(ll m,ll n) { if(m<n) return 0; if(n==0) return 1; if(m<mod) return cal(m,m-n)*inv[n]%mod; return C(m/mod,n/mod)*C(m%mod,n%mod)%mod; } ll n,s,f[23]; int main() { scanf("%lld%lld",&n,&s); ll fac=1; for(ll i=1;i<=n;i++) { fac=fac*i%mod; inv[i]=quickpow(fac,mod-2); scanf("%lld",f+i); } ll ans=0; for(int i=0;i<1<<n;i++) { ll m=s+n-1,cnt=0; for(int j=0;j<n;j++) if(i>>j&1) m-=f[j+1],cnt++; (ans+=(cnt&1?-1ll:1ll)*C(m-cnt,n-1))%=mod; } printf("%lld\n",(ans%mod+mod)%mod); return 0; }
2018.10,17