• CF711E ZS and The Birthday Paradox


    Solution

    原题最后的答案比较难求,所以我们可以反方向思考:只需要求出所有人生日不同的概率。

    显然这个概率为 (dfrac{A_{2^n}^m}{2^{nm}}=dfrac{prod_{i=2^n-m+1}^{2^n-1}}{2^{n(m-1)}})

    分母部分用快速幂即可,而分子部分需要我们思考一下,因为模数为 (10^6+3) ,当 (m) 大于模数时,分子的因数必有一项为模数的倍数,答案可输出 (0) ,其他情况暴力求解即可。

    但是,这个题还有一个需要注意的地方是分数的约分。因为分母为 (2) 的幂,所以找出分子中 (2) 的幂次即可。这里用到了 (Legendre's~formula) 。因为对于所有 (1leq aleq 2^n) ,都有 (a)(2^n-a)(2) 的幂次相同,所以求出 ((m-1)!) 中的 (2) 的次数就好了。

    时间复杂度: (O(log k+log n))

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define ll long long
    
    using namespace std;
    const int mod=1e6+3;
    ll n,k,num=0,fz=1,fm=1;
    
    ll fpow(ll a,ll b){
        ll res=1;
        while(b){
            if(b&1) res=res*a%mod;
            a=a*a%mod;
            b>>=1;
        }
        return res;
    }
    
    int main(){
        scanf("%lld%lld",&n,&k);
        num=1;
        while((1LL<<num)<k)  num++;
        if(num>n){
            printf("1 1");
            return 0;
        }
        num=0;
        for(ll i=k-1;i>=1;i>>=1) num+=(i>>1);
        ll a=fpow(2,n);
        fz=1;
        for(int i=1;i<k;i++){
            fz=(ll)fz*(a-i+mod)%mod;
            if(fz==0) break;
        }
        fm=fpow(a,k-1);
        int inv=fpow(fpow(2,num),mod-2);
        fz=(ll)fz*inv%mod,fm=(ll)fm*inv%mod;
        fz=(fm-fz+mod)%mod;
        printf("%lld %lld",fz,fm);
        return 0;
    }
    
  • 相关阅读:
    分治
    递归
    java三大特性之封装
    Java基础知识
    puk2367 拓扑排序
    puk1251 最小生成树
    puk1521 赫夫曼树编码
    DOSbox简单运行操作
    Mybatis初学经验----------------(2)
    mysql存储引擎MyISAM和InnoDB的区别
  • 原文地址:https://www.cnblogs.com/jasony/p/13641428.html
Copyright © 2020-2023  润新知