[CEOI2004] Sweets

D06發表於2024-06-26
  • 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;
}