多重集组合数模板题。
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const ll mod=1e9+7;
ll inv,a[25],m;
int n;
void exgcd(ll a,ll b,ll &x,ll &y)
{
if(!b)
{
x=1;
y=0;
return ;
}
exgcd(b,a%b,y,x);
y-=(a/b)*x;
}
ll C(ll x)
{
if(x<n-1) return 0;
ll ans=1;
x%=mod;
for(int i=0;i<n-1;i++) ans=ans*(x-i)%mod;
return ans*inv%mod;
}
int main()
{
cin>>n>>m;
ll x,y,jc=1;
for(int i=1;i<n;i++) jc=jc*i%mod;
exgcd(jc,mod,x,y);
inv=(x%mod+mod)%mod;
for(int i=0;i<n;i++) cin>>a[i];
ll ans=0;
for(int i=0;i<(1<<n);i++)//i!=(1<<n)那i就有n+1位而不是n位了
{
ll t=n+m-1,p=0;
for(int j=0;j<n;j++) if(i&(1<<j))
{
t-=a[j];
++p;
}
t-=p;//别忘了-p
if(p&1) ans=(ans-C(t))%mod;
else ans=(ans+C(t))%mod;
}
cout<<(ans+mod)%mod<<endl;//在前面的运算每一步都有%mod时,最后即使为负数绝对值也小于mod,不需要(ans%mod+mod)%mod
system("pause");
}