题目:一年有2^n天,有k个人,他们的生日有冲突的概率是多少?答案用最简分数表示,分子分母对1e6+3取模。1 ≤ n ≤ 10^18, 2 ≤ k ≤ 10^18。
答案为 1 - A(2^n,k) / (2^n)^k,分子与分母的gcd必定为2^i。计算A(2^n,k)=(2^n) * (2^n-1) * ... * (2^n-k+1)含多少个因子2,相当于计算0~k-1中总共有多少个因子2。
因为分子乘以了模mod后就永远是0了,所以可以O(mod)的算出分子。求出gcd后乘上gcd的逆元就可以了。
1 #include <map> 2 #include <set> 3 #include <stack> 4 #include <queue> 5 #include <ctime> 6 #include <vector> 7 #include <cstdio> 8 #include <cctype> 9 #include <cstring> 10 #include <cstdlib> 11 #define eps 1e-15 12 #define PI acos(-1) 13 #define INF 100000007 14 #define MAX(a,b) (a>b?a:b) 15 #define MIN(a,b) (a<b?a:b) 16 #define mem(a) memset(a,0,sizeof(a)) 17 #define N 400005 18 #define P 1000003 19 long long n,k,i,p,q,x,ans,kk,ny; 20 21 long long pow(long long a,long long b) 22 { 23 long long ans=1; 24 while (b>0) 25 { 26 if (b&1==1) 27 ans=(ans*a)%P; 28 b>>=1; 29 a=(a*a)%P; 30 } 31 return ans; 32 } 33 int main() 34 { 35 scanf("%I64d%I64d",&n,&k); 36 if (n<63) 37 { 38 if ((1ll<<n)<k) 39 { 40 printf("1 1 "); 41 return 0; 42 } 43 44 } 45 x=pow(2,n); 46 p=1; 47 for (i=1;i<k;i++) 48 { 49 x--; 50 p=(p*x)%P; 51 if (p==0) break; 52 } 53 kk=k-1; 54 while (kk>0) 55 { 56 ans+=kk/2; 57 kk=kk>>1; 58 } 59 ny=pow(pow(2,P-2),ans); 60 p=(p*ny)%P; 61 q=(pow(pow(2,n),k-1)*ny)%P; 62 p=q-p; 63 if (p<0)p+=P; 64 printf("%I64d %I64d ",p,q); 65 return 0; 66 }
# | When | Who | Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|---|---|---|
20280606 | 2016-08-30 16:20:59 | lbz007 | E - ZS and The Birthday Paradox | GNU C++ | Accepted | 31 ms | 0 KB |