码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ4665 : 小w的喜糖

时间:2016-08-22 19:57:15      阅读:323      评论:0      收藏:0      [点我收藏+]

标签:

考虑枚举哪些人一定不合法,那么方案数可以通过简单的排列组合算出。

于是设$f[i][j]$表示前$i$种糖果,一共有$j$个人一定不合法的方案数,但是这样并不能保证其他人一定合法,所以需要进行容斥。

最后将答案除以每种糖果数量的阶乘,即可保证本质不同。

时间复杂度$O(n^2)$。

 

#include<cstdio>
const int N=2005,P=1000000009;
int n,i,j,k,x,a[N],C[N][N],fac[N],inv[N],f[N][N],tmp,ans;
int main(){
  scanf("%d",&n);
  for(i=1;i<=n;i++)scanf("%d",&x),a[x]++;
  for(C[0][0]=i=1;i<=n;i++)for(C[i][0]=j=1;j<=i;j++)C[i][j]=(C[i-1][j-1]+C[i-1][j])%P;
  for(fac[0]=fac[1]=inv[0]=inv[1]=1,i=2;i<=n;i++){
    fac[i]=1LL*fac[i-1]*i%P;
    inv[i]=1LL*(P-inv[P%i])*(P/i)%P;
  }
  for(i=2;i<=n;i++)inv[i]=1LL*inv[i]*inv[i-1]%P;
  for(f[0][0]=i=1;i<=n;i++)for(j=0;j<=n;j++)for(k=0;k<=a[i]&&k<=j;k++)
    f[i][j]=(1LL*f[i-1][j-k]*C[a[i]][k]%P*fac[a[i]]%P*inv[a[i]-k]+f[i][j])%P;
  for(i=0;i<=n;i++){
    tmp=1LL*f[n][i]*fac[n-i]%P;
    if(i&1)ans=(ans-tmp+P)%P;else ans=(ans+tmp)%P;
  }
  for(i=1;i<=n;i++)ans=1LL*ans*inv[a[i]]%P;
  return printf("%d",ans),0;
}

  

BZOJ4665 : 小w的喜糖

标签:

原文地址:http://www.cnblogs.com/clrs97/p/5796771.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!