干这题需要用到数学排列组合的思想假设每个花瓶里面的花无限支,然后再排除那些花瓶超出限制的个数,然后根据lucas的公式就是求C(n,m)%p= lucas(n,m)=C(n%p,m%p)*lucas(n/p,m/p)%p,求C(n,m)%p 因为p = 1e9+7是一个素数所以可以根据费马小定理就是C(n,m)%p = n*(n-1)*(n-2)*....(n-m+1)*(1*2*...*m)^p-2%p;
就是当p是素数的时候a/b%p = a*b^p-2%p;
然后用容斥定理求出总个数-超限制的个数求出来的结果就是答案
用隔板法求出不考虑超限制的方案数是C(S+n-1,n-1);
同样求超限制的方案相减 容斥中假设A B两个花瓶超限制那么总超限制就是
C(s+n-1-Fa-1,n-1)+C(s+n-1-Fb-1,n-1)-C(s+n-1-Fb-1-Fa-1,n-1)
二进制是个好东西用二进制求这个方案即可
#include
#include
#include
using namespace std;
typedef long long int ll;
const ll p = 1e9+7;
ll f[30];
ll quick(ll x,ll n){
ll ans = 1;
while(n){
if(n&1) ans = ans*x%p;
x = x*x%p;
n /= 2;
}
return ans;
}
ll get_c(ll n, ll m ){
if(m > n) return 0;
if(n-m < m) m = n-m;
if(m == 0) return 1;
ll f1 = 1,f2 = 1;
for(int i = 1; i <= m; i++){
f1 = f1*((n-i+1)%p)%p;
f2 = f2*(i%p)%p;
}
return f1*quick(f2,p-2)%p;
}
ll lucas(ll n,ll m){
if(m>n)return 0;
if(m == 0)
return 1;
return lucas(n/p,m/p)*get_c(n%p,m%p)%p;
}
int main(){
ll n,s,sum;
while(cin>>n>>s){
for(int i = 0; i < n; i++)
cin>>f[i];
sum = lucas(s+n-1,n-1);
ll d = 1<