• AcWing214 Devu和鲜花 (容斥原理)


    经典容斥原理,这其实是离散数学解不定方程或者高中组合数学的隔板法。

    原问题可以转换为 x1+x2+x3+...xn=M+N;

    又因为每个都有限制需要<=a[i],因此我们可以反向考虑,总数-不合法数

    而不合法数是所有>a[i]的合集,因此可以用容斥原理拆分,这里可以用二进制的表示方法表示取哪几个。

    代码中还有其他细节:

    请注意一定要防止爆int或者爆ll,随时取模+观察

    #include<algorithm>
    #include<iostream>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<string> 
    #include<set>
    #include<map>
    #include<queue>
    using namespace std;
    typedef long long ll;
    const int N=1e5+10;
    const int mod=1e9+7;
    ll n,m;
    ll s[N];
    int down=1;
    int qmi(int a,int k){
        int res=1;
        while(k){
            if(k&1)
            res=(ll)res*a%mod;
            a=(ll)a*a%mod;
            k>>=1;
        }
        return res;
    }
    int C(ll a,ll b){
        if(a<b) //有可能存在减去数量很多的花导致要求的a小于b,那么这种情况是不存在的,所以返回0; 
        return 0;
        ll i;
        int up=1;
        for(i=a;i>a-b;i--){
            up=(i%mod*up%mod)%mod;
        }
        return (ll)up*down%mod;
    }
    int main(){
       cin>>n>>m;
       int i;
       for(i=0;i<n;i++)
       cin>>s[i];
       for(i=1;i<=n-1;i++)
       down=(ll)down*i%mod;
       down=qmi(down,mod-2);
       int res=0;
       for(i=0;i<1<<n;i++){
           ll a=m+n-1,b=n-1;
           int sign=1;
           for(int j=0;j<n;j++){
               if(i>>j&1){
                   sign*=-1;
                   a-=s[j]+1;//这+1是因为我们在求隔板的时候都要求至少有一个,而-s[j]会有取0的情况 
               }
           }
           res=(res+sign*C(a,b))%mod;
       }
       cout<<(res+mod)%mod<<endl;
    }
    View Code
  • 相关阅读:
    shiro实战系列(三)之架构
    shiro实战系列(二)之入门实战续
    ShopNC B2B2C多用户商城2014商业版,带微商城
    开源 SHOPNC B2B2C结算营运版 wap IM客服 API 手机app 短信通知
    PHP5.3下加速器ZendGuardLoader安装 (LNMP/lnmpa)
    XAMPP + Xdebug+Zend Studio
    magento 12 配置安装教程
    C#控件一览表
    GetXamarin.xambe
    新建电子监控点与测速点
  • 原文地址:https://www.cnblogs.com/ctyakwf/p/12368971.html
Copyright © 2020-2023  润新知