【题解】分特产(组合数+容斥)

【题解】分特产(组合数+容斥)

一道小水题。

假如没有这个要求每个人都要有一个特产的限制我们直接可以组合数。

我们又发现人(本质上)是没有区别的,所以容斥的复杂度只有\(O(n)\)

\(n\)个人分\(m\)个特产,每个特产有\(a_i\)个,人可以不拿特产,的方案数就是把\(a_i\)分成\(n\)份,而且可以分为\(0\)份。

这个的答案就是
\[ f(n)=\prod_{i=1}^m {a_i+n-1\choose n-1} \]
意思就是有\(a_i+n\)个球分成不为空\(n\)份的方案,新建\(n\)个球,选了这\(n\)个球代表你不选。

于是我们就可以容斥出来我们要的答案。
\[ \sum_{i=0}^{n-1} (-1)^if(n-i) \]
哦要解释一下这个式子的意思,\(f(x)\)里面的方案数包括了所有大于\(x>\)它的的方案数。我们才要容斥。

所以枚举钦定至少\(i\)个人一个也没有,最终我们要的是0个人一个也没有。

//@winlere
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long

using namespace std;  typedef long long ll;
inline int qr(){
      register int ret=0,f=0;
      register char c=getchar();
      while(c<48||c>57)f|=c==45,c=getchar();
      while(c>=48&&c<=57) ret=ret*10+c-48,c=getchar();
      return f?-ret:ret;
}
const int mod=1e9+7;
const int maxn=2e3+5;
int jc[maxn];
int inv[maxn];
int data[maxn];
inline int Pow(int base,const int&p){
      register int ret=1;
      for(register int t=p;t;t>>=1,base=1ll*base*base%mod)
        if(t&1)ret=1ll*ret*base%mod;
      return ret;      
}

inline int c(const int&n,const int&m){
      if(n<m||m<0)return 0;
      return 1ll*jc[n]*inv[m]%mod*1ll*inv[n-m]%mod;
}

signed main(){

      jc[0]=inv[0]=1;
      for(register int t=1;t<maxn;++t)
        jc[t]=1ll*jc[t-1]*t%mod,inv[t]=Pow(jc[t],mod-2);
      int n=qr(),m=qr();
      for(register int t=1;t<=m;++t)
        data[t]=qr();
      int ans=0;
      for(register int t=0,delta;t<n;++t){
        delta=c(n,t);
        for(register int i=1;i<=m;++i)
          delta=1ll*delta*c(data[i]+n-t-1,n-t-1)%mod;
        if(t&1)delta=mod-delta;
        ans=(ans+delta)%mod;
      }
      cout<<ans<<endl;      
      return 0;
}

转载于:https://www.cnblogs.com/winlere/p/11017582.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值