BZOJ4665 小 w 的喜糖 题解

BZOJ4665 小 w 的喜糖

这道题可以说是二项式反演的经典应用。

第一次转化,题目中说使每个人手里的糖都不相同,类似于错排问题,而我们显然是不好直接进行处理的。于是考虑转化为计算使一部分人手里的糖与原来相同的方案数,如果记作 \(g(i)\),那么答案就是 \(g(0)\)

第二次转化,看到恰好,于是用二项式反演转化为求钦定。记钦定的方案为 \(f(i)\),则二项式反演的公式为

\[g(i)=\sum_{j=i}^n(-1)^{j-i}\binom jif(j) \]

既然我们只需要求出 \(g(0)\),那么根据上述公式,就有

\[g(0)=\sum_{j=0}^n(-1)^jf(j) \]

考虑如何求出 \(f(0),f(1),\dots,f(n)\)。不妨用 DP 来求解,设 \(\mathit{dp}(i,j)\) 表示枚举到第 \(i\) 种喜糖,钦定 \(j\) 个人拿到的糖和原来相同的方案数。发现同种喜糖是相同的,而这一限制比较麻烦,不妨认为所有喜糖都是互不相同的,而我们只需在最后给答案乘上 \(\prod1/c_i!\) 即可,其中 \(c_i\) 是第 \(i\) 种喜糖的数量。这样我们就暂时不用考虑去重问题,有转移方程

\[\mathit{dp}(i,j)=\sum_{k=0}^{\min(j,c_i)}\mathit{dp}(i-1,j-k)\times\binom{c_i}k\times\mathrm A_{c_i}^k \]

简单来说就是枚举在所有钦定的人中,有多少人的糖在当前种类里,即 \(k\)。那么我们首先要从原来就是这种糖的人中选出 \(k\) 个人,然后再挑出 \(k\) 个糖按顺序放在这些人手上。所以会先乘排列数然后乘组合数。

边界条件显然是 \(\mathit{dp}(0,0)=1\)。这样算下来之后,我们的 \(f(i)\) 实际上是 \(\mathit{dp}(m,i)\times(n-i)!\),因为 \(\mathit{dp}(i,j)\) 的转移方程里只计算了钦定的方案数,而没有计算钦定以外的人随意排列的方案数。

那么现在我们有了 \(f(i)\),就能算出 \(g(0)\),然后再乘上 \(\prod1/c_i!\),这个题就做完了。

#include<bits/stdc++.h>
using namespace std;

using ll=long long;
constexpr int MAXN=2005;
constexpr ll MOD=1e9+9;
int n,c[MAXN],m;
ll fac[MAXN],inv[MAXN];
ll f[MAXN][MAXN];
ll power(ll a,ll b){
    ll res=1;
    for(;b;a=a*a%MOD,b>>=1)if(b&1)res=res*a%MOD;
    return res;
}
void init(int n){
	fac[0]=1;
	for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i%MOD;
	inv[n]=power(fac[n],MOD-2);
	for(int i=n-1;~i;i--) inv[i]=inv[i+1]*(i+1)%MOD;
}
ll C(int n,int m){
	if(n<m) return 0;
	return fac[n]*inv[m]%MOD*inv[n-m]%MOD;
}
ll A(int n,int m){
	if(n<m) return 0;
	return fac[n]*inv[n-m]%MOD;
}

int main(){
	cin.tie(nullptr)->sync_with_stdio(0);
	cin>>n;
	init(n);
	for(int i=1,x;i<=n;i++) cin>>x,c[x]++,m=max(m,x);
	f[0][0]=1;
	for(int i=1,pre=c[1];i<=m;i++,pre+=c[i])
		for(int j=0;j<=pre;j++)
			for(int k=0;k<=min(j,c[i]);k++)
				f[i][j]=(f[i][j]+f[i-1][j-k]*C(c[i],k)%MOD*A(c[i],k))%MOD;
	ll ans=0;
	for(int i=0;i<=n;i++) ans=(ans+f[m][i]*fac[n-i]*(i&1?-1:1))%MOD;
	for(int i=1;i<=m;i++) ans=ans*inv[c[i]]%MOD;
	cout<<(ans+MOD)%MOD<<'\n';
	return 0;
}
posted @ 2025-06-29 21:16  Laoshan_PLUS  阅读(237)  评论(0)    收藏  举报