Codeforces 451E Devu and Flowers容斥原理+卢卡斯定理

Posted lokiii

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces 451E Devu and Flowers容斥原理+卢卡斯定理相关的知识,希望对你有一定的参考价值。

题意:每个箱子里有\( f[i] \)种颜色相同的花,现在要取出\( s \)朵花,问一共有多少种颜色组合
首先枚举\( 2^n \)种不满足条件的情况,对于一个不被满足的盒子,我们至少拿出\( f[i]+1 \)朵花。
然后进行容斥,不满足奇数个条件的减去,不满足偶数个条件的加上

#include<iostream>
#include<cstdio>
using namespace std;
const int N=25,mod=1e9+7;
int n;
long long s,f[N];
long long ksm(long long a,long long b)
{
    long long r=1ll;
    while(b)
    {
        if(b&1)
            r=r*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return r;
}
long long C(long long a,long long b)
{
    if(a<b)
        return 0;
    b=(b>a-b)?a-b:b;
    long long u=1ll,d=1ll;
    for(long long i=0;i<b;i++)
    {
        u=u*(a-i)%mod;
        d=d*(i+1)%mod;
    }
    return u*ksm(d,mod-2)%mod;
}
long long lucas(long long a,long long b)
{
    return !b?1:C(a%mod,b%mod)*lucas(a/mod,b/mod)%mod;
}
int main()
{
    scanf("%d%I64d",&n,&s);
    for(int i=1;i<=n;i++)
        scanf("%I64d",&f[i]);
    long long ans=0ll;
    for(int i=0;i<(1<<n);i++)
    {
        long long t=1ll,sum=s;
        for(int j=1;j<=n;j++)
            if(i&(1<<(j-1)))
            {
                sum-=f[j]+1;
                t*=-1;
            }
            if(sum<0)
                continue;
            ans+=t*lucas(sum+n-1,n-1);
    }
    printf("%I64d\n",(ans%mod+mod)%mod);
    return 0;
}

以上是关于Codeforces 451E Devu and Flowers容斥原理+卢卡斯定理的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 258E Devu and Flowers

codeforces 439 E. Devu and Birthday Celebration 组合数学 容斥定理

Codeforces 451 E. Devu and Flowers(组合数学,数论,容斥原理)

容斥例题Devu and Flowers

容斥例题Devu and Flowers

Devu and Flowers lucas定理+容斥原理