• 题解 洛谷 P3726 【[AH2017/HNOI2017]抛硬币】


    可以分别枚举两人正面朝上的次数来统计答案,所求即为

    [sum_{i=0}^{a}sum_{j=0}^{b} inom{a}{i} inom{b}{j} [i>j] ]

    (i)替换为(i+j)来保证(i>j)

    [ egin{aligned} &sum_{i=0}^{a}sum_{j=0}^{b} inom{a}{i} inom{b}{j} [i>j] \ =&sum_{i=1}^{a}sum_{j=0}^{a-i} inom{a}{i+j} inom{b}{j} \ =&sum_{i=1}^{a}sum_{j=0}^{a-i} inom{a}{i+j} inom{b}{b-j} end{aligned} ]

    由范德蒙德卷积得

    [ egin{aligned} &sum_{i=1}^{a}sum_{j=0}^{a-i} inom{a}{i+j} inom{b}{b-j}\ =&sum_{i=1}^{a} inom{a+b}{b+i} \ =&sum_{i=b+1}^{a+b} inom{a+b}{i} end{aligned} ]

    直接求化简后的式子复杂度无法接受,但发现(a)(b)的差值很小,所以将式子进一步转化得

    [ egin{aligned} &sum_{i=b+1}^{a+b} inom{a+b}{i} \ =&sum_{i=lceil frac{a+b}{2} ceil}^{a+b} inom{a+b}{i}+sum_{i=b+1}^{lfloor frac{a+b}{2} floor} inom{a+b}{i} end{aligned} ]

    第一项的值可以快速计算,当(a+b)为奇数时,其为(2^{a+b-1}),当(a+b)为偶数时,其为(2^{a+b-1}-frac{1}{2}inom{a+b}{frac{a+b}{2}}),第二项的值用扩展卢卡斯计算组合数即可。

    用扩展卢卡斯计算组合数时,可以预处理阶乘和进行特判来优化。

    (code:)

    #include<bits/stdc++.h>
    #define maxn 2000010
    #define inf 2000000000
    using namespace std;
    typedef long long ll;
    ll a,b,t,k2,k5,mod,ans,x,y;
    ll f[6][maxn];
    ll exgcd(ll a,ll b)
    {
        if(!b)
        {
            x=1,y=0;
            return a;
        }
        ll ans=exgcd(b,a%b),tmp=x;
        x=y,y=tmp-a/b*y;
        return ans;
    }
    ll inv(ll a,ll p)
    {
        if(!a) return 0;
        exgcd(a,p);
        return (x%p+p)%p;
    }
    ll qp(ll x,ll y,ll p)
    {
        ll v=1;
        while(y)
        {
            if(y&1) v=v*x%p;
            x=x*x%p,y>>=1;
        }
        return v;
    }
    ll fac(ll x,ll p,ll k)
    {
        if(!x) return 1;
        return qp(f[p][k],x/k,k)*f[p][x%k]%k*fac(x/p,p,k)%k;
    }
    ll C(ll n,ll m,ll p,ll k,bool type)
    {
        if(n<m) return 0;
        ll sum=0,v=1;
        for(ll i=n;i;i=i/p) sum+=i/p;
        for(ll i=m;i;i=i/p) sum-=i/p;
        for(ll i=n-m;i;i=i/p) sum-=i/p;
        if(type)
        {
            if(p==2) sum--;
            else v=inv(2,k);
        }
        if(sum>=t) return 0;
        return v*fac(n,p,k)%k*qp(p,sum,k)%k*inv(fac(m,p,k),k)%k*inv(fac(n-m,p,k),k)%k;
    }
    ll crt(ll x,ll p)
    {
        return x*inv(mod/p,p)%mod*(mod/p)%mod;
    }
    ll exlucas(ll n,ll m,bool type)
    {
        if(n<m) return 0;
        return (crt(C(n,m,2,k2,type),k2)+crt(C(n,m,5,k5,type),k5))%mod;
    }
    void init()
    {
        f[2][0]=f[5][0]=1;
        for(int i=1;i<=512;++i)
        {
            f[2][i]=f[2][i-1];
            if(i&1) f[2][i]=f[2][i]*i%512;
        }
        for(int i=1;i<=1953125;++i)
        {
            f[5][i]=f[5][i-1];
            if(i%5) f[5][i]=f[5][i]*i%1953125;
        }
    }
    int main()
    {
        init();
        while(scanf("%lld%lld%lld",&a,&b,&t)!=EOF)
        {
            mod=qp(10,t,inf),ans=qp(2,a+b-1,mod),k2=qp(2,t,inf),k5=qp(5,t,inf);
            for(ll i=b+1;i<=(a+b)/2;++i) ans=(ans+exlucas(a+b,i,0))%mod;
            if((a+b)%2==0) ans=(ans-exlucas(a+b,(a+b)/2,1)+mod)%mod;
            printf("%0*lld
    ",t,ans);
        }
        return 0;
    }
    
  • 相关阅读:
    详细,Qt Creator快捷键大全,附快捷键配置方法
    Qt Creator 你必须要掌握的快捷操作
    Linux 终端下颜色的输出
    Qt之JSON生成与解析
    Ubuntu配置和修改IP地址
    USB的VID和PID,以及分类(Class,SubClass,Protocol)
    fatal error: gst/gst.h
    VID、PID查询
    el表达式具体解释
    F
  • 原文地址:https://www.cnblogs.com/lhm-/p/12940377.html
Copyright © 2020-2023  润新知