关闭

Codeforces 711E. ZS and The Birthday Paradox

标签: codeforcesgcd
67人阅读 评论(0) 收藏 举报
分类:

题目链接

题目大意

  假设一年有2^n天,问k个小朋友中有两个小朋友生日相同的概率。

  假设该概率约分后为 p / q ,输出p , q对1000003取模的解。

  n , k <= 10^18。

解题分析

  若k > 2^n 则答案为1 / 1 , 否则答案为 1 - A(2^n,k) / (2^n)^k ,

  可以发现分子与分母的gcd必定为(2^i)*(2^n)。

因为A(2^n,k)=(2^n)(2^n-1)(2^n-2)(2^n-3)(2^n-4)…..=(2^n)(2^n-1)(2*(2^(n-1)-1))(2^n-3)(2*2*(2^(n-2)-1)
也就是说只和减掉的数有关!!!
然后这里去求i发现i就是1到k-1中2的次数。
然后就是k-1不停除2相加就是了。

然后gcd的逆元就是quickpowmod(quickpowmod(2,num,mod),mod-2,mod)

然后就GG了

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
#define mod 1000003
const int maxn=200005;

LL quickpowmod(LL x,LL y,LL mo)
{
      LL ret = 1;
      while(y){
         if(y&1)
             ret = ret*x%mo;
         x = x*x%mo;
         y >>= 1;
     }
   return ret;
}
LL n,k,num;

int main()
{
    scanf("%I64d%I64d",&n,&k);
     if (n<=60 && k>(1ll<<n)){
         printf("1 1\n");
         return 0;
     }
    num=0;
    LL t=k-1;
    while(t){
        t/=2;
        num+=t;
    }
    t=quickpowmod(2,n,mod);
    LL ans=1;
    LL ans1=1;
    for(LL i=1;i<=k-1;i++){
        ans=ans*(--t)%mod;
        if(ans==0)break;
    }
    ans1=quickpowmod(quickpowmod(2,n,mod),k-1,mod);
    LL inv=quickpowmod(quickpowmod(2,num,mod),mod-2,mod);
    ans1=ans1*inv%mod;
    ans=ans*inv%mod;
    ans=(ans1-ans+mod)%mod;
    printf("%I64d %I64d\n",ans,ans1);
    return 0;
}
0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:34793次
    • 积分:3040
    • 等级:
    • 排名:第11485名
    • 原创:282篇
    • 转载:2篇
    • 译文:0篇
    • 评论:1条
    文章分类