Codeforces 711 E. ZS and The Birthday Paradox(數學)——Codeforces Round #369 (Div. 2)
ZS the Coder has recently found an interesting concept called the Birthday Paradox. It states that given a random set of 23 people, there is around 50% chance that some two of them share the same birthday. ZS the Coder finds this very interesting, and decides to test this with the inhabitants of Udayland.
In Udayland, there are 2n days in a year. ZS the Coder wants to interview k people from Udayland, each of them has birthday in one of 2n days (each day with equal probability). He is interested in the probability of at least two of them have the birthday at the same day.
ZS the Coder knows that the answer can be written as an irreducible fraction
The first and only line of the input contains two integers n and k (1 ≤ n ≤ 1018, 2 ≤ k ≤ 1018), meaning that there are 2n days in a year and that ZS the Coder wants to interview exactly k
If the probability of at least two k people having the same birthday in 2n days long year equals (A ≥ 0, B ≥ 1, ), print the A and B in a single line.
Since these numbers may be too large, print them modulo 106 + 3. Note that A and B must be coprime before their remainders modulo 106 + 3 are taken.
ExamplesInput3 2Output
1 8Input
1 3Output
1 1Input
4 3Output
23 128Note
In the first sample case, there are 23 = 8 days in Udayland. The probability that 2 people have the same birthday among 2 people is clearly , so A = 1, B = 8.
In the second sample case, there are only 21 = 2 days in Udayland, but there are 3 people, so it is guaranteed that two of them have the same birthday. Thus, the probability is 1 and A = B = 1.
題目大意:
一年有
小朋友生日相同的概率是多少,假設這個概率約分後為
解題思路:
首先我們來分析一下題目,因為題目中說 至少 兩個小朋友生日相同的概率,那麼我們從反面來考慮,那麼也就是說所有
的小朋友的生日都不相同的概率是多少,那麼我們這個可以列出一個式子:
那麼我來解釋一下這個式子:首先因為有
相同的,所以就是從
那麼我們通過觀察可以得出結論:分子和分母的最大公約數一定是
別除以最大公約數就行了,因為分子的
首先可以先將
實我們仔細觀察一下的話,會發現如果
力做就行了,得到分子之後別忘記除以
接輸出
/**
2016 - 08 - 30 晚上
Author: ITAK
Motto:
今日的我要超越昨日的我,明日的我要勝過今日的我,
以創作出更好的程式碼為目標,不斷地超越自己。
**/
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
#include <queue>
#include <algorithm>
#include <set>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int INF = 1e9+5;
const int MAXN = 1e3+5;
const LL MOD = 1e6+3;
const double eps = 1e-7;
const double PI = acos(-1);
using namespace std;
LL Scan_LL()///輸入外掛
{
LL res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
int Scan_Int()///輸入外掛
{
int res=0,ch,flag=0;
if((ch=getchar())=='-')
flag=1;
else if(ch>='0'&&ch<='9')
res=ch-'0';
while((ch=getchar())>='0'&&ch<='9')
res=res*10+ch-'0';
return flag?-res:res;
}
void Out(LL a)///輸出外掛
{
if(a>9)
Out(a/10);
putchar(a%10+'0');
}
LL Multi(LL a, LL b)
{
LL ans = 0;
while(b)
{
if(b & 1)
ans = (ans+a)%(MOD-1);
b>>=1LL;
a = (a+a)%(MOD-1);
}
return ans;
}
LL quick(LL a, LL b)
{
LL ans = 1;
while(b)
{
if(b & 1)
ans = (ans*a) % MOD;
b>>=1LL;
a = (a*a) % MOD;
}
return ans;
}
void Exgcd(LL a, LL b, LL &x, LL &y)
{
if(b == 0)
{
x = 1;
y = 0;
return;
}
LL x1, y1;
Exgcd(b, a%b, x1, y1);
x = y1;
y = x1 - (a/b)*y1;
}
int main()
{
LL Inv, y;
Exgcd(2, MOD, Inv, y);
Inv = (Inv%MOD+MOD)%MOD;
LL n, k;
while(cin>>n>>k)
{
if(n < 63LL)
{
if(k > (1LL<<n))
puts("1 1");
else
{
LL ans = 0, fm = k, tmp;
fm--;
while(fm)
{
fm>>=1LL;
ans += fm;
}
fm = k-1LL;
fm = Multi(n, fm);
fm = (fm-ans)%(MOD-1);
fm = (fm%(MOD-1)+(MOD-1))%(MOD-1);
fm = quick(2LL, fm);
if(k > MOD)
{
cout<<fm<<" "<<fm<<endl;
continue;
}
tmp = quick(2LL, n);
LL fz = 1;
for(LL i=1; i<k; i++)
fz = fz*(tmp-i)%MOD;
fz = (fz%MOD+MOD)%MOD;
fz = fz*quick(Inv, ans)%MOD;
fz = fm - fz;
fz = (fz%MOD+MOD)%MOD;
cout<<fz<<" "<<fm<<endl;
}
}
else
{
LL ans = 0, fm = k, tmp;
fm--;
while(fm)
{
fm>>=1LL;
ans += fm;
}
/** 2^ans 是最大公約數 **/
fm = k-1LL;
fm = Multi(n, fm);
fm = (fm-ans)%(MOD-1);
fm = (fm%(MOD-1)+(MOD-1))%(MOD-1);
fm = quick(2LL, fm);
if(k > MOD)
{
cout<<fm<<" "<<fm<<endl;
continue;
}
tmp = quick(2LL, n);
LL fz = 1;
for(LL i=1; i<k; i++)
fz = fz*(tmp-i)%MOD;
fz = fz*quick(Inv, ans)%MOD;
fz = fm - fz;
fz = (fz%MOD+MOD)%MOD;
cout<<fz<<" "<<fm<<endl;
}
}
return 0;
}