[CEOI2004] Sweets
容斥板子,不知道为啥题解都是生成函数
考虑可重集容斥,对于$ S=\begin{Bmatrix} n_1\cdot a_1,n_2\cdot a_2,\cdots,n_k\cdot a_k, \end{Bmatrix}$表示由 \(n_1\) 个 \(a_1\) , \(n_2\) 个 \(a_2\) ,…, \(n_k\) 个 \(a_k\) 组成的多重集。那么对于正整数 \(r\) ,从 \(S\) 中选择 \(r\) 个元素组成一个多重集的方案数。
通过容斥这个东西的答案为 $ Ans= \sum_{A} ( -1)^{|A|} \binom{ k+r-1- \sum_{A} n_{A_i}-|A| } {k-1} $
带回原式子$ Ans= \sum_{A} ( -1)^{|A|} \sum_{r=a}^{b}\limits \binom{ n+r-1- \sum_{A} m_{A_i}-|A| } {n-1} $
尝试把右面一坨化一下,$$\sum_{r=a}^{b}\limits \binom{ n+r-1- \sum_{A} m_{A_i}-|A| } {n-1} $$
令 \(X=n-1-\sum_{A} m_{A_i}-|A| ,m=n-1\)
这时候我们的问题变为处理 $\sum_{i=0}^{x}\limits \binom{ n+i } {m} $ ,再换一下:$\sum_{i=n}^{x+n}\limits \binom{ i } {m} $ , 然后继续拆 : \(\sum_{i=0}^{x+n}\limits \binom{ i } {m}-\sum_{i=0}^{n-1}\limits \binom{ i } {m}\)
然后 \(\sum_{i=0}^{n}\limits \binom{ i } {m}\) 就可以求了,还是那个范德蒙德卷积,公式不放了,以前博客有, \(\sum_{i=0}^{n}\limits \binom{ i } {m}=\binom{ n+1 } {m+1}\) 。再带回原式子即可
令 $X=n-1-\sum_{A} m_{A_i}-|A| $
一个比较特殊的点,向 \(wlesq\) 学习了一下,模数不是质数,观察到组合数有一项都是 \(n\),且 \(n<=10\),所以直接让模数乘 \(n!\),在组合数中用新模数暴力求,复杂度 \(O(2^n n)\)
点击查看代码
#include<bits/stdc++.h>
#define int long long
const int mod=2004;
const int maxn=1e7+100;
using namespace std;
int n,m[11],a,b,ans;
int c(int n,int m)
{
if(m>n) return 0;
int M=2004,x=1,y=1;
for(int i=1;i<=m;i++) x*=i,M*=i;
for(int i=n-m+1;i<=n;i++) y=y*i%M;
return (y/x)%mod;
}
signed main()
{
// freopen("T.in","r",stdin);
// freopen("T.out","w",stdout);
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>a>>b;
for(int i=1;i<=n;i++) cin>>m[i];
for(int i=0;i<(1<<n);i++)
{
int num=0,sum=0;
for(int j=9;j>=0;j--)
if((1<<j)&i) sum+=m[j+1],num++;
int x=n-1-sum-num;
if(!(num&1)) ans=((((ans+c(b+x+1,n))%mod-c(b,n)+mod)%mod-c(a+x,n)+mod)%mod+c(a-1,n))%mod;
else ans=((((ans-c(b+x+1,n)+mod)%mod+c(b,n))%mod+c(a+x,n))%mod-c(a-1,n)+mod)%mod;
}
cout<<ans;
return 0;
}
/*
*/