ZS and The Birthday Paradox

题目链接:http://codeforces.com/contest/711/problem/E

数学题(Legendre's formula)

这题是以生日悖论(如果有23个或23个以上的人,那么至少有两个人的生日相同的概率要大于50%)为背景的数学题。公式本身不难推,主要是对大数的处理。

首先,我们需要找到分子和分母的公因数,这里用到了Legendre's formula(举个例子:10!的因数中质数3的个数为[10/3+10/(3^2)])。因为若2^n-x与2^n有公因数,那么x与2^n有相同的公因数,所以求(2^n)(2^n-1)(2^n-2)*...*(2^n-k+1)与(2^n)^k的公因数,就转化为了求(k-1)!与(2^n)^k的公因数。

之后就是分别求分子和分母:

对于分母来说,只需要用快速幂(也可以用费马小定理)就可以很容易的求出,再乘上公因数的逆元即可;

而对于分子来说,稍微有点麻烦:

1.如果k>=M,即(2^n)(2^n-1)(2^n-2)*...*(2^n-k+1)中至少有连续的M个整数,

那么(2^n)(2^n-1)(2^n-2)*...*(2^n-k+1)一定为M的倍数,所以它被M求模后余0;

2.如果k<M,因为M很小,所以枚举一下,就可以求出分子,再乘上公因数的逆元即可。

总的时间复杂度为O(M+lgk+lgn)

(感谢游少半夜教我证明Orz)

证明:(A/B)modM=(A*(BmodM)')modM,其中B'为B在M下的逆元

令B=b1*b2*b3*...*bn,则((BmodM)')modM

=((b1*b2*b3*...*bn mod M)')modM

=(b1modM*b2modM*...*bn mod M)'modM

=(b1*b2*...*bn)modM*(b1modM*b2modM*...*bn mod M)'modM*(b1*b2*...*bn)'modM

=(b1modM*b2modM*...*bn mod M)*(b1modM*b2modM*...*bn mod M)'modM*(b1*b2*...*bn)'modM

=1*(b1*b2*...*bn)'modM=(b1*b2*...*bn)'modM

=b1*b1'modM*b2*b2'modM...bn*bn'mod M*(b1*b2*...*bn)'modM

=(b1*b2*...*bn)modM*(b1'modM*b2'modM...bn'mod M)*(b1*b2*...*bn)'modM

=b1'modM*b2'modM...bn'mod M

代码如下:

 #include<cstdio>
#include<iostream>
#define M (long long)(1e6+3)
using namespace std;
typedef long long LL;
LL n,k,cnt,molecular,numerator,x,y;
LL exGCD(LL a,LL b){
if(b==){
x=,y=;
return a;
}
LL r=exGCD(b,a%b);
LL temp=x;
x=y;
y=temp-(a/b)*y;
return r;
}
LL mod(LL a,LL b){
LL base=a,temp=;
while(b){
if(b&)temp=(temp*base)%M;
base=(base*base)%M;
b>>=;
}
return temp;
}
int main(void){
cin>>n>>k;
if(n<=&&k>(((LL))<<n)){//总人数大于总天数
cout<<""<<" "<<""<<endl;
return ;
}
LL temp=;
while(k->=temp){//根据Legendre's formula,求出(k-1)!的因数中质数2的个数
cnt+=((k-)/temp);
temp<<=;
}
if(cnt){//若有公因数,则求出公因数的逆元
LL gcd=mod(,cnt);
exGCD(gcd,M);
x=(x+M)%M;
}else x=;//若没有公因数,则令x=1,来消除对后面计算的影响
temp=mod(,n);//计算2^n
numerator=(mod(temp,k-)*x)%M;//计算(2^n)^(k-1)
if(k>=M)molecular=;//若分子出现连续的M个整数,则分子一定为M的倍数
else{
molecular=;
for(LL i=;i<k;++i){
molecular=((temp-i+M)%M*molecular)%M;//计算分子
}
molecular=(molecular*x)%M;//除以公因数
}
molecular=(numerator-molecular+M)%M;
cout<<molecular<<" "<<numerator<<endl;
}

ZS and The Birthday Paradox的更多相关文章

  1. codeforces 711E E. ZS and The Birthday Paradox(数学+概率)

    题目链接: E. ZS and The Birthday Paradox. time limit per test 2 seconds memory limit per test 256 megaby ...

  2. Codeforces 711E ZS and The Birthday Paradox 数学

    ZS and The Birthday Paradox 感觉里面有好多技巧.. #include<bits/stdc++.h> #define LL long long #define f ...

  3. Codeforces Round #369 (Div. 2) E. ZS and The Birthday Paradox 数学

    E. ZS and The Birthday Paradox 题目连接: http://www.codeforces.com/contest/711/problem/E Description ZS ...

  4. 【Codeforces711E】ZS and The Birthday Paradox [数论]

    ZS and The Birthday Paradox Time Limit: 20 Sec  Memory Limit: 512 MB Description Input Output Sample ...

  5. CF369E. ZS and The Birthday Paradox

    /* cf369E. ZS and The Birthday Paradox http://codeforces.com/contest/711/problem/E 抽屉原理+快速幂+逆元+勒让德定理 ...

  6. Codeforces 711E ZS and The Birthday Paradox

    传送门 time limit per test 2 seconds memory limit per test 256 megabytes input standard input output st ...

  7. cf711E ZS and The Birthday Paradox

    ZS the Coder has recently found an interesting concept called the Birthday Paradox. It states that g ...

  8. 【28.57%】【codeforces 711E】ZS and The Birthday Paradox

    time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...

  9. codeforces 711E. ZS and The Birthday Paradox 概率

    已知一年365天找23个人有2个人在同一天生日的概率 > 50% 给出n,k ,表示现在一年有2^n天,找k个人,有2个人在同一天生日的概率,求出来的概率是a/b形式,化到最简形式,由于a,b可 ...

随机推荐

  1. 读headFirst设计模式 - 策略模式

    有些人已经解决你的问题了 什么是设计模式?我们为什么要使用设计模式?怎样使用?按照书上的说法和我自己的理解,我认为是这样的:我们遇到的问题其他开发人员也遇到过,他们利用他们的智慧和经验将问题解决了,把 ...

  2. 五、RDD持久化

    Spark最重要的一个功能是它可以通过各种操作(operations)持久化(或者缓存)一个集合到内存中.当你持久化一个RDD的时候,每一个节点都将参与计算的所有分区数据存储到内存中,并且这些数据可以 ...

  3. CART分类与回归树与GBDT(Gradient Boost Decision Tree)

    一.CART分类与回归树 资料转载: http://dataunion.org/5771.html        Classification And Regression Tree(CART)是决策 ...

  4. Linux下产生随机密码10方法

    有特殊符号的: cat /dev/urandom | tr -dc "a-zA-Z0-9_+\~\!\@\#\$\%\^\&\*"| fold -w 16 |head -n ...

  5. Cocos2d-x 3.x事件分发机制总结

    在2.x中处理事件需要用到委托代理(delegate),相信学过2.x的触摸事件的同学,都知道创建和移除的流程十分繁琐.而在3.x中由于加入了C++11的特性,而对事件的分发机制通过事件分发器Even ...

  6. URL传值问题,不同浏览器对URL的长度要求

    通过URL传值的问题,所以对url字符串进行encodeURIComponent对url字符串内容进行编码,问题解决,但是有时候会出现 The request filtering module is ...

  7. CentOS 7安装redis及php扩展

    安装remi源 # wget http://rpms.famillecollet.com/enterprise/remi-release-7.rpm # rpm -Uvh remi-release-7 ...

  8. 如何对Javascript代码进行二次压缩(混淆)

    如何对Javascript代码进行二次压缩(混淆) 对Javascript代码进行压缩(混淆),可以有效减少传输和加载时间.但是,不是所有的变量(方法)都能被混淆的,一般来说,只有非属性的变量(方法) ...

  9. 数据结构之Heap (Java)

    Heap简介 Heap译为“堆”,是一种特殊的树形数据结构,它满足所有堆的特性:父节点的值大于等于子节点的值(max heap),或者小于等于子节点的值(min heap).对于max heap 根节 ...

  10. codevs3027线段覆盖2(DP)题解

    题目描述 Description 数轴上有n条线段,线段的两端都是整数坐标,坐标范围在0~1000000,每条线段有一个价值,请从n条线段中挑出若干条线段,使得这些线段两两不覆盖(端点可以重合)且线段 ...