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 . He wants to find the values of A and B (he does not like to deal with floating point numbers). Can you help him?
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 people.
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.
3 2
1 8
1 3
1 1
4 3
23 128
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.
想要知道答案是啥还是很容易的,用高中知识即可知道1 - { A(2^n,k) / 2^(nk) } 即是所求,A(a,b)是排列数。
问题是要先化简再上下同时取模
可以先证明如果有大数A、B,假设(A%mod)/(B%mod)==p/q,那么1-A/B=(B-A)/B=(q-p)/q。(在模mod意义下)
所以只要知道A(2^n,k)/2^(nk),就能知道答案了
先化简。
分式下面只有2,所以gcd=2^t,t不知道,但是显然t是由上面A(2^n,k)决定。
考虑(2^n)(2^n-1)...(2^n-k+1)有多少个因子2。如果把2^n单独考虑,剩下(2^n-1)...(2^n-k+1)的2的因子数跟1~k-1的2的因子数一样多。因为任取个(2^n-s),它能和s对应
所以因子数就是n+(k-1)/2+(k-1)/4+...+(k-1)/2^p,除到(k-1)/2^p=0为止
得到了gcd=2^t的t之后,只要上下同时乘(2关于mod的逆元)乘t次,就完成了化简。
然后注意到当k>=mod时,(2^n)(2^n-1)(2^n-mod+1)%mod==0,由鸽巢原理这是显然的。
所以当k<mod,A(2^n,k)%mod暴力算,k>=mod,A(2^n,k)%mod==0。
而2^(nk)%mod是容易算的。
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<algorithm> 6 #include<cmath> 7 #include<queue> 8 #include<deque> 9 #include<set> 10 #include<map> 11 #include<ctime> 12 #define LL long long 13 #define inf 0x7ffffff 14 #define pa pair<int,int> 15 #define mkp(a,b) make_pair(a,b) 16 #define pi 3.1415926535897932384626433832795028841971 17 #define mod 1000003 18 using namespace std; 19 inline LL read() 20 { 21 LL x=0,f=1;char ch=getchar(); 22 while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();} 23 while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} 24 return x*f; 25 } 26 LL n,k; 27 LL rev_2; 28 LL bit[65]; 29 inline LL quickpow(LL a,LL b,LL MOD) 30 { 31 LL s=1; 32 while (b) 33 { 34 if (b&1)s=(s*a)%MOD; 35 a=(a*a)%MOD; 36 b>>=1; 37 } 38 return s; 39 } 40 int main() 41 { 42 rev_2=quickpow(2,mod-2,mod);bit[0]=1;for (int i=1;i<63;i++)bit[i]=bit[i-1]<<1; 43 n=read();k=read(); 44 if (n<=60&&k>bit[n]){puts("1 1");return 0;} 45 if (k==1){puts("0 1");return 0;} 46 LL mx=quickpow(2,n,mod),now=mx; 47 LL ans1=1,ans2=1; 48 LL te=k-1,sum=n; 49 while (te) 50 { 51 sum+=te/2; 52 te>>=1; 53 } 54 LL sv=k; 55 for (LL i=1;i<=min(sv,(LL)mod);i++) 56 { 57 k--; 58 ans2=(ans2*mx)%mod; 59 ans1=(ans1*now)%mod; 60 now--;if (!now)now+=mod; 61 } 62 while (k%(mod-1)!=0)ans2=(ans2*mx)%mod,k--; 63 ans1=(ans1*quickpow(rev_2,sum,mod))%mod; 64 ans2=(ans2*quickpow(rev_2,sum,mod))%mod; 65 printf("%lld %lld ",(ans2-ans1+mod)%mod,ans2); 66 //ans=1-{ (2^n*(2^n-1)*(2^n-2)*...*(2^n-k+1))/(2^n)^k } 67 }