您的位置:首页 > 其它

Codeforces 711E. ZS and The Birthday Paradox

2016-08-31 13:14 423 查看
题目链接

题目大意

  假设一年有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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  codeforces gcd