题目链接
- 写出朴素的生成函数后用等比数列求和公式化简
- 10!=3628800 \(10^6\)级别
- 中国剩余定理可用于处理没有平方因子的合数为模数的情况
- 本题中的模数2004含有平方因子,可以先用扩展Lucas定理求组合数再用中国剩余定理,更简便的方法是,考虑到本题中只需要除以n!,在过程中对2004*n!阶乘取模,最后再除以n!
- 不要局限自己的优化思路
- 通过dfsO(\(2^n\))的处理所有情况
- 利用组合数的递推公式简化计算,不妨画出杨辉三角形
点击查看代码
#include <bits/stdc++.h>
using namespace std;
long long mod=2004,jc=1;
int m[15],n;
long long calc(int p)
{
long long s=1;
for(int i=0;i<n;i++)
{
s=s*(p-i)%mod;
}
return s;
}
int main()
{
int a,b;
cin>>n>>a>>b;
for(int i=1;i<=n;i++)
{
jc=jc*i;
}
mod=mod*jc;
for(int i=1;i<=n;i++)
{
cin>>m[i];
}
long long ans=0;
for(int i=0;i<(1<<n);i++)
{
int sum=0,opt=1;
for(int j=0;j<n;j++)
{
if(((i>>j)&1)==1)
{
sum=sum+m[j+1]+1;
opt=-opt;
}
}
if(sum<=b)
{
long long tmp=0;
if(a-sum>0)
{
tmp=calc(n+b-sum)-calc(n+a-sum-1);
}
else
{
tmp=calc(n+b-sum);
}
ans=ans+tmp*opt%mod;
}
}
ans=ans%mod;
cout<<(((ans+mod)%mod)/jc)%2004<<endl;
return 0;
}