BZOJ 3027 Sweets 生成函数,容斥

Posted Lsxxxxxxxxxxxxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了BZOJ 3027 Sweets 生成函数,容斥相关的知识,希望对你有一定的参考价值。

Description

John得到了n罐糖果。不同的糖果罐,糖果的种类不同(即同一个糖果罐里的糖果种类是相同的,不同的糖果罐里的糖果的种类是不同的)。第i个糖果罐里有 mi个糖果。John决定吃掉一些糖果,他想吃掉至少a个糖果,但不超过b个。问题是John 无法确定吃多少个糖果和每种糖果各吃几个。有多少种方法可以做这件事呢?  
  
 

Input


从标准输入读入每罐糖果的数量,整数a到b
 
John能够选择的吃掉糖果的方法数(满足以上条件)  
 

Output


 
把结果输出到标准输出(把答案模 2004 输出) 

1<=N<=10,0<=a<=b<=10^7,0<=Mi<=10^6

Sample Input

2 1 3
3
5

Sample Output

9

HINT

(1,0),(2,0),(3,0),(0,1),(0,2),(0,3),(1,1),(1,2),(2,1)

 

解法:

 

 

typedef long long LL;
const int mod = 2004;
int n, a, b, ans, m, v[20];
int C(int n,int m)
{
    if (n<m) return 0;
    LL t=1; LL p1=1;
    for (int i=1;i<=m;i++) p1=p1*i;
    LL mod2=(LL)mod*p1;
    for (int i=n-m+1;i<=n;i++) t=(LL)t*i%mod2;
    return (t/p1)%mod;
}
void dfs(int x, int cnt, int sum){
    if(x==n+1){
        if(cnt&1) ans-=C(n+m-sum,n);
        else ans+=C(n+m-sum,n);
        ans %= mod;
        return;
    }
    dfs(x+1,cnt,sum);
    dfs(x+1,cnt+1,sum+v[x]);
}
int f(int x){
    ans=0;
    m=x;
    dfs(1,0,0);
    return ans;
}
int main()
{
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1; i<=n; i++) scanf("%d", &v[i]), v[i]++;
    int ans = f(b)-f(a-1);
    printf("%d\\n", (ans%mod+mod)%mod);
    return 0;
}

 

此题

 

以上是关于BZOJ 3027 Sweets 生成函数,容斥的主要内容,如果未能解决你的问题,请参考以下文章

bzoj 3027: [Ceoi2004]Sweet (生成函数)

bzoj 3027: [Ceoi2004]Sweet生成函数+组合数学

bzoj 3771 Triple FFT 生成函数+容斥

BZOJ 3771: Triple [快速傅里叶变换 生成函数 容斥原理]

BZOJ 2986 莫比乌斯函数+容斥原理

bzoj4596/luoguP4336 [SHOI2016]黑暗前的幻想乡(矩阵树定理,容斥)