zoukankan      html  css  js  c++  java
  • cf711E ZS and The Birthday Paradox

    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?

    Input

    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.

    Output

    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.

    Examples
    Input
    3 2
    Output
    1 8
    Input
    1 3
    Output
    1 1
    Input
    4 3
    Output
    23 128
    Note

    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 }
    cf 711E
  • 相关阅读:
    BZOJ4240: 有趣的家庭菜园
    BZOJ1509: [NOI2003]逃学的小孩
    BZOJ5301: [Cqoi2018]异或序列
    BZOJ4540: [Hnoi2016]序列
    BZOJ4956: [Wf2017]Secret Chamber at Mount Rushmore
    BZOJ2141: 排队
    BZOJ1833: [ZJOI2010]count 数字计数
    HDU2089: 不要62
    BZOJ5178: [Jsoi2011]棒棒糖
    BZOJ3439: Kpm的MC密码
  • 原文地址:https://www.cnblogs.com/zhber/p/7283971.html
Copyright © 2011-2022 走看看