隔板法

[Lucas定理][隔板法][容斥原理] Codeforces 451E Devu and Flowers

耗尽温柔 提交于 2019-11-26 23:24:16
题解 我们先考虑没有限制的情况怎么求,也就是在n个盒子里取出s个球的方案数,每个盒子可以不取就是隔板法C(n+s-1,n-1) 然后考虑减去每不合法的方案,也就是i个盒子取超的方案数 考虑容斥原理,容易想到容斥系数就是(-1)^i,那么就拿总方案数-1个盒子超+2个盒子超... 然后还是要用Lucas定理来求,因为n和m太大 代码 1 #include <cstdio> 2 #include <iostream> 3 #define ll long long 4 using namespace std; 5 const ll mo=1e9+7,N=30; 6 int n; 7 ll s,r,f[N]; 8 ll ksm(ll a,ll b) { for (r=1;b;b>>=1,a=a*a%mo) if (b&1) r=r*a%mo; return r; } 9 ll C(ll n,ll m) 10 { 11 if (m>n) return 0; 12 if (m>n-m) m=n-m; 13 ll ans=1ll,fac=1ll; 14 for (int i=1;i<=m;i++) ans=(ans*(n-i+1))%mo,fac=fac*i%mo; 15 fac=ksm(fac,mo-2),ans=ans*fac%mo; 16 return ans; 17 } 18 ll