A. On The Way to Lucky Plaza
time limit per test

1.0 s

memory limit per test

256 MB

input

standard input

output

standard output

Alaa is on her last day in Singapore, she wants to buy some presents to her family and friends. Alaa knows that the best present in the world will be a chocolate plate for each one of her family members and friends.

Alaa goes to Lucky Plaza shopping mall in Orchard road in order to find all chocolate she needs. Lucky Plaza is a big mall and have many shops that sell chocolate.

On the entrance of Lucky Plaza Alaa wondered if she wants to buy k chocolate plates, what is the probability that she will buy the kthchocolate plate from the nth shop she will visit, knowing that she can visit each shop at most one time. Also she can buy at most one chocolate plate from each shop, and the probability to do that is p. (This probability is the same for all shops in Lucky Plaza)

Alaa wants to finish her mission as soon as possible, so she starts visiting the shops, also she asked you to calculate the answer of her hard question. Can you?

Input

The first line contains three integers mnk and real number p (1  ≤  mnk  ≤  105) (0  ≤  p  ≤  1), where m is the number of shops that sell chocolate in Lucky Plaza, n is the number of shops Alaa will visit, k is the number of chocolate plates Alaa wants to buy, and p is the probability that Alaa will buy a chocolate plate from any shop that sell chocolate.

The probability p is given with exactly three digits after the decimal point

Output

On a single line print y, where y is the sought probability computed modulo 109 + 7.

The answer y is defined precisely as follows. Represent the probability that Alaa will buy the kth chocolate plate from the nth shop she will visit as an irreducible fraction p / q. The number y then must satisfy the modular equation y × q ≡ p (mod 109 + 7), and be between 0 and 109 + 6, inclusive. It can be shown that under the constraints of this problem such a number y always exists and is uniquely determined.

Examples
input

Copy
5 1 1 0.500
output

Copy
500000004
input

Copy
9 4 2 0.800
output

Copy
417600003
input

Copy
100 5 5 0.200
output

Copy
714240005
Note

In the first test case there are 5 shops that sell chocolate in Lucky Plaza, and Alaa wants to buy only 1 chocolate plate. In this case Alaa wants to know what is the probability that she will buy the 1st chocolate plate from the 1st shop she will visit. The probability is 1 / 2, and the answer is 500000004, since (500000004 * 2) % (109 + 7) = 1 % (109 + 7).

In the second test case there are 9 shops that sell chocolate in Lucky Plaza, and Alaa wants to buy only 2 chocolate plates. In this case Alaa wants to know what is the probability that she will buy the 2nd chocolate plate from the 4th shop she will visit. The probability is 48 / 625, and the answer is 417600003, since (417600003 * 625) % (109 + 7) = 48 % (109 + 7).

题解:博客

概率,线性递推求乘法逆元。
找到公式,就是求a*b%mod=C(n-1,k-1)*p^k*(1-p)^n-k%mod
转化成a=C(n-1,k-1)*p^k*(1-p)^n-k*inv(b)%mod;
先把p转化成一个long long的类型,注意a消除浮点误差,然后就是用杨辉三角求出组合数,最后就是求b的乘法逆元。

这里要注意的地方有不能直接用杨辉三角把组合数求出来,因为中间可能会超过mod,所以还是要一步一步的递推过去,然后再乘以一个乘法逆元。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 100;
const int mod = 1e9 + 7;
const double eps = 1e-10;
ll inv[maxn]; int main()
{
int m, n, k;
double p;
inv[1] = 1;
for (int i = 2; i < maxn; i++) inv[i] = (mod - mod / i)*1ll*inv[mod%i]%mod; cin >> m >> n >> k >> p;
if(m<n||k>n)
{
printf("0\n");
return 0;
}
ll p1 = p * 1000 + eps,ans=1;
//求组合数
for (int i = 1; i <= k - 1; i++) ans = ans * (n - i) % mod;
for (int i = 1; i <= k - 1; i++) ans = ans * inv[i] % mod; for (int i = 1; i <= k; i++) ans = ans * p1%mod;
for (int i = 1; i <= n - k; i++) ans = ans * (1000 - p1) % mod; for (int i = 1; i <= n; i++) ans = ans * inv[1000] % mod; printf("%lld\n", ans);
return 0;
}

  

然后介绍一下三种求乘法逆元的方法:

乘法逆元
对于两个数a,p若gcd(a,p)=1则一定存在另一个数b,使得ab≡1(modp),并称此时的b为a关于1模p的乘法逆元。我们记此时的b为inv(a)或 。 举个例子:5×3≡1(mod14),我们称此时的3为5关于1模14的乘法逆元。 如何求乘法逆元?
方法一:费马小定理
费马小定理:当有两数a,p满足gcd(a,p)=1时,则有ap≡a(modp)。
变一下形:a* ≡1(modp)。是不是和上面的乘法逆元的定义是相似的?
所以,我们可以使用快速幂求出 ,即求出a的逆元。
long long PowMod(long long a,int b) {
long long ret=1;
while(b) {
if(b&1)ret=ret*a%Mod; //b&1 在这里和b%2 的含义一样
a=a*a%Mod;
b>>=1;
}
return ret;
} 方法二:扩展欧几里得算法
由定义可知:ab≡1(modp),这个式子等价于已知a,p求一个二元一次不定方程ab=kp+1,移一下项得:ab−kp=1。这东西不是扩展欧几里得算法?
long long extend_gcd(long long a,long long b,long long &x,long long &y) {
if(a==0&&b==0)
return -1;
if(b==0)
{
x=1;
y=0;
return a;
}
long long d=extend_gcd(b,a%b,y,x);
y-=a/b*x;
return d;
}
long long mod_reverse(long long a,long long n) {
long long x,y,d=extend_gcd(a,n,x,y);
if(d==1) {
if(x%n<=0)return x%n+n;
else return x%n;
} else return -1;
} 方法三:递推计算阶乘的逆元
当我们要计算一大串连续的阶乘的逆元时,采用费马小定理或扩展欧几里得算法就有可能超时,所以我们必须采用一个更快的算法。
令 ,则可得:
(mod p)
我们将(i+1)(i+1)乘过去,则有:
(mod p)
自然我们就得出递推式。
乘法逆元的作用?
我们由费马小定理可得:a* ≡1(modp)。
所以:
≡ ≡1/a(modp)
我们又知道模运算的乘法结合律:
a/b≡b* ≡b* (modp)
所以我们可以知道:a除以一个数模p,等于a乘这个数的乘法逆元模p。
f[0]=1;
for(int i=1;i<=N;i++)
f[i]=f[i-1]*i%Mod;
inv[0]=1;
inv[N]=PowMod(f[N],Mod-2);
for(int i=N-1;i>0;i--)
inv[i]=inv[i+1]*(i+1)%Mod; 下为几种方法求逆元的代码实现
int inv[1000010];
LL ksm(LL a,LL b,LL mod)
{
int ans=1;
while(b)
{
if(b&1) ans=(ans*a)%mod;
a=(a*a)%mod;
b>>=1;
}
return ans;
}
LL exgcd(LL a,LL b,LL &x,LL &y)
{
if(!b)
{
x=1;
y=0;
return a;
}
LL GCD=exgcd(b,a%b,x,y);
LL tmp=x;
x=y;
y=tmp-a/b*y;
return GCD;
}
LL inv1(LL a,LL mod)//扩展欧几里得求逆元
{
LL x,y;
LL d=exgcd(a,mod,x,y);
if(d==1) return (x%mod+mod)%mod;
return -1;
}
LL inv2(LL a,LL mod)//费马小定理
{
return ksm(a,mod-2,mod);
}
void inv3(LL mod)//线性递推求逆元
{
inv[1]=1;
for(int i=2;i<=mod-1;i++)
{
inv[i]=(mod-mod/i)*inv[mod%i]%mod;
cout<<inv[i]<<" ";
}
}
int main()
{
LL n,mod;
while(cin>>n>>mod)
{
cout<<inv1(n,mod)<<" "<<inv2(n,mod)<<endl;
inv3(mod);
}
}

  

然后再加一个杨辉三角求组合数:

组合数:
按照杨辉三角(递推):
memset(c,0,sizeof(c));
for (int i=0; i<=n; i++){
c[i][0]=1;
for (int j=1; j<=i; j++)
c[i][j]=c[i-1][j-1]+c[i-1][j];
}
优化形式---利用 :
c[0]=1;
for (int i=1; i<=n; i++) c[i]=c[i-1]*(n-i+1)/i;

  

A. On The Way to Lucky Plaza 概率 乘法逆元的更多相关文章

  1. Codeforces gym 101343 A. On The Way to Lucky Plaza【概率+逆元+精度问题】

     2017 JUST Programming Contest 2.0 题目链接:http://codeforces.com/gym/101343/problem/A A. On The Way to ...

  2. HDU5985 Lucky Coins 概率dp

    题意:给你N种硬币,每种硬币有Si个,有Pi 概率朝上,每次抛所有硬币抛起,所有反面的拿掉,问每种硬币成为最后的lucky硬币的概率. 题解:都知道是概率dp,但是模拟赛时思路非常模糊,很纠结,dp[ ...

  3. HDU 5985/nowcoder 207D - Lucky Coins - [概率题]

    题目链接:https://www.nowcoder.com/acm/contest/207/D 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5985 ...

  4. HDU.5985.Lucky Coins(概率DP)

    题目链接 \(Description\) 有n(n<=10)种硬币,已知每种硬币的数量和它抛一次正面朝上的概率pi.进行如下过程:每次抛一次所有硬币,将正面朝下的硬币去掉.重复该过程直到只剩一种 ...

  5. 【BZOJ】3566: [SHOI2014]概率充电器

    [算法]树型DP+期望DP [题意]一棵树上每个点均有直接充电概率qi%,每条边有导电概率pi%,问期望有多少结点处于充电状态? [题解]引用自:[BZOJ3566][SHOI2014]概率充电器 树 ...

  6. 算法讲堂二:组合数学 & 概率期望DP

    组合数学 1. 排列组合 1. 加法原理 完成一列事的方法有 n 类,其中第 i 类方法包括\(a_i\)种不同的方法,且这些方法互不重合,则完成这件事共有 \(a_1 + a_2 + \cdots ...

  7. gym101343 2017 JUST Programming Contest 2.0

    A.On The Way to Lucky Plaza  (数论)题意:m个店 每个店可以买一个小球的概率为p       求恰好在第m个店买到k个小球的概率 题解:求在前m-1个店买k-1个球再*p ...

  8. POJ 2472 106 miles to Chicago(Dijstra变形——史上最坑的最长路问题)

    题目链接 :http://poj.org/problem?id=2472 Description In the movie "Blues Brothers", the orphan ...

  9. 2017 JUST Programming Contest 2.0 题解

    [题目链接] A - On The Way to Lucky Plaza 首先,$n>m$或$k>m$或$k>n$就无解. 设$p = \frac{A}{B}$,$ans = C_{ ...

随机推荐

  1. 阿里云redis映射到阿里云服务器

    参考文档:https://help.aliyun.com/document_detail/43850.html?spm=a2c4g.11186623.2.3.7yg9VH ECS Windows 篇 ...

  2. [android] 采用layoutInflater打气筒创建一个view对象

    上一节知道了ListView的工作原理,数据也展示出来了,但是TextView显示的非常难看,如果想美化一下,就先创建好一个布局出来,这个布局采用了两层LinearLayout嵌套,外层的水平方向,内 ...

  3. Java高并发 -- 并发扩展

    Java高并发 -- 并发扩展 主要是学习慕课网实战视频<Java并发编程入门与高并发面试>的笔记 死锁 死锁是指两个或两个以上的事务在执行过程中,因争夺锁资源而造成的一种互相等待的现象, ...

  4. 谈谈MySQL支持的事务隔离级别,以及悲观锁和乐观锁的原理和应用场景?

    在日常开发中,尤其是业务开发,少不了利用 Java 对数据库进行基本的增删改查等数据操作,这也是 Java 工程师的必备技能之一.做好数据操作,不仅仅需要对 Java 语言相关框架的掌握,更需要对各种 ...

  5. Reinforcement Learning: An Introduction读书笔记(4)--动态规划

     > 目  录 <  Dynamic programming Policy Evaluation (Prediction) Policy Improvement Policy Iterat ...

  6. JS动态创建元素

    动态添加标签,可从服务器获取标签文本,然后加载到指定div中,可用于权限控制. 1.添加标签字符串方式 var str='<div>5555555555555555555555555555 ...

  7. canvas-a10isPointPath.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  8. 有状态(Stateful)与无状态(Stateless)

    1.有状态(Stateful): 有数据存储功能.有状态对象(Stateful Bean),就是有实例变量的对象,可以保存数据,类里面有成员变量,而且成员变量是可变的,是非线程安全的.在不同方法调用间 ...

  9. SAP MM 按采购订单查询付款信息的报表?

    SAP MM 按采购订单查询付款信息的报表? 上午给P3项目采购部门用户做了一个采购相关的报表的培训.培训过程中,客户的采购部门经理提出了一个问题:有没有报表能查询到各个采购订单的付款情况,显示采购订 ...

  10. Elasticsearch alias别名管理小结

    Elasticsearch alias别名管理小结 By:授客 QQ:1033553122 建创测试数据 1 创建别名 2 移除别名 3 创建测试数据 4 批量操作 5 例1. 5 例2. 把多个索引 ...