BZOJ4665小w的喜糖 容斥+组合数

Posted CQzhangyu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ4665小w的喜糖 容斥+组合数相关的知识,希望对你有一定的参考价值。

【BZOJ4665】小w的喜糖

Description

废话不多说,反正小w要发喜糖啦!!
小w一共买了n块喜糖,发给了n个人,每个喜糖有一个种类。这时,小w突发奇想,如果这n个人相互交换手中的糖,那会有多少种方案使得每个人手中的糖的种类都与原来不同。
两个方案不同当且仅当,存在一个人,他手中的糖的种类在两个方案中不一样。

Input

第一行,一个整数n
接下来n行,每行一个整数,第i个整数Ai表示开始时第i个人手中的糖的种类
对于所有数据,1≤Ai≤k,k<=N,N<=2000

Output

一行,一个整数Ans,表示方案数模1000000009

Sample Input

6
1
1
2
2
3
3

Sample Output

10

题解:显然我们应该将每种糖果放在一起处理,用v[i]表示有多少人有第i种糖果。然后考虑容斥,用f[i][j]表示前i种糖果,至多j个人的糖果与原来不同的方案数,然后很容易DP求出f数组。

$f[i][j]=\sum\limits_{k=0}^{v[i]}f[i-1][j-k]*C_{v[i]}^{k}*(v[i])*(v[i]-1)*...*(v[i]-k+1)$

发现我们在DP过程中并没有考虑我们选出来那j个人的顺序,所以最后f[i][j]乘上j!即可。最后因为每个糖果是相同的,所以方案数要除以v[i]!。

 

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;

const ll P=1000000009;
int n,m;
ll ans;
int col[2010],s[2010],v[2010];
ll c[2010][2010],f[2010][2010],jc[2010],ine[2010],jcc[2010];
inline int rd()
{
	int ret=0,f=1;	char gc=getchar();
	while(gc<‘0‘||gc>‘9‘)	{if(gc==‘-‘)	f=-f;	gc=getchar();}
	while(gc>=‘0‘&&gc<=‘9‘)	ret=ret*10+gc-‘0‘,gc=getchar();
	return ret*f;
}
int main()
{
	n=rd();
	int i,j,k;
	for(i=0;i<=n;i++)
	{
		c[i][0]=1;
		for(j=1;j<=i;j++)	c[i][j]=(c[i-1][j-1]+c[i-1][j])%P;
	}
	jc[0]=ine[0]=jcc[0]=jc[1]=ine[1]=jcc[1]=1;
	for(i=2;i<=n;i++)
	{
		jc[i]=jc[i-1]*i%P,ine[i]=P-(P/i)*ine[P%i]%P,jcc[i]=jcc[i-1]*ine[i]%P;
	}
	for(i=1;i<=n;i++)	col[i]=rd();
	sort(col+1,col+n+1);
	for(i=1;i<=n;i++)
	{
		if(col[i]>col[i-1])	m++;
		v[m]++;
	}
	for(i=1;i<=m;i++)	s[i]=s[i-1]+v[i];
	f[0][0]=1;
	for(i=1;i<=m;i++)	for(j=0;j<=s[i-1];j++)	for(k=0;k<=v[i];k++)
		f[i][j+k]=(f[i][j+k]+f[i-1][j]*c[v[i]][k]%P*jc[v[i]]%P*jcc[v[i]-k]%P)%P;
	for(i=0;i<=n;i++)
	{
		ans=(ans+((i&1)?-1:1)*f[m][i]*jc[n-i]+P)%P;
	}
	for(i=1;i<=m;i++)	ans=ans*jcc[v[i]]%P;
	printf("%lld",ans);
	return 0;
}

 

以上是关于BZOJ4665小w的喜糖 容斥+组合数的主要内容,如果未能解决你的问题,请参考以下文章

●BZOJ 4665 小w的喜糖

[bzoj4665]小w的喜糖_二项式反演

BZOJ3782上学路线 组合数+容斥+CRT

[BZOJ 2440][中山市选2011]完全平方数(容斥原理/莫比乌斯函数+二分)

BZOJ2839集合计数 组合数+容斥

bzoj4767两双手 容斥+组合