A. On The Way to Lucky Plaza 概率 乘法逆元
1.0 s
256 MB
standard input
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?
The first line contains three integers m, n, k and real number p (1 ≤ m, n, k ≤ 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
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.
5 1 1 0.500
500000004
9 4 2 0.800
417600003
100 5 5 0.200
714240005
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 概率 乘法逆元的更多相关文章
- 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 ...
- HDU5985 Lucky Coins 概率dp
题意:给你N种硬币,每种硬币有Si个,有Pi 概率朝上,每次抛所有硬币抛起,所有反面的拿掉,问每种硬币成为最后的lucky硬币的概率. 题解:都知道是概率dp,但是模拟赛时思路非常模糊,很纠结,dp[ ...
- HDU 5985/nowcoder 207D - Lucky Coins - [概率题]
题目链接:https://www.nowcoder.com/acm/contest/207/D 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5985 ...
- HDU.5985.Lucky Coins(概率DP)
题目链接 \(Description\) 有n(n<=10)种硬币,已知每种硬币的数量和它抛一次正面朝上的概率pi.进行如下过程:每次抛一次所有硬币,将正面朝下的硬币去掉.重复该过程直到只剩一种 ...
- 【BZOJ】3566: [SHOI2014]概率充电器
[算法]树型DP+期望DP [题意]一棵树上每个点均有直接充电概率qi%,每条边有导电概率pi%,问期望有多少结点处于充电状态? [题解]引用自:[BZOJ3566][SHOI2014]概率充电器 树 ...
- 算法讲堂二:组合数学 & 概率期望DP
组合数学 1. 排列组合 1. 加法原理 完成一列事的方法有 n 类,其中第 i 类方法包括\(a_i\)种不同的方法,且这些方法互不重合,则完成这件事共有 \(a_1 + a_2 + \cdots ...
- gym101343 2017 JUST Programming Contest 2.0
A.On The Way to Lucky Plaza (数论)题意:m个店 每个店可以买一个小球的概率为p 求恰好在第m个店买到k个小球的概率 题解:求在前m-1个店买k-1个球再*p ...
- POJ 2472 106 miles to Chicago(Dijstra变形——史上最坑的最长路问题)
题目链接 :http://poj.org/problem?id=2472 Description In the movie "Blues Brothers", the orphan ...
- 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_{ ...
随机推荐
- [MySQL] INFORMATION_SCHEMA 数据库包含所有表的字段
sql注入后可以通过该数据库获取所有表的字段信息 1. COLLATIONS表 提供有关每个字符集的排序规则的信息. COLLATIONS表包含以下列: COLLATION_NAME 排序规则名称. ...
- 2.QT-窗口组件(QWidget),QT坐标系统,初探消息处理(信号与槽)
本章主要内容如下: 1) 窗口组件(QWidget) 2) QT坐标系统 3) 消息处理(信号与槽) 窗口组件(QWidget) 介绍 Qt以组件对象的方式构建图形用户界面 Qt中没有父组件的顶级组件 ...
- 【Java每日一题】20170324
20170323问题解析请点击今日问题下方的“[Java每日一题]20170324”查看(问题解析在公众号首发,公众号ID:weknow619) package Mar2017; public cla ...
- python面向对象学习(五)多态
多态 多态:不同的 子类对象 调用相同的 父类方法,产生不同的执行结果 多态 可以 增加代码的灵活度 以 继承 和 重写父类方法 为前提 是调用方法的技巧,不会影响到类的内部设计 多态案例练习 需求 ...
- jQuery中页面返回顶部的方法总结
当页面过长时,通常会在页面下方有一个返回顶部的button,总结一下,大概三种实现方法,下面说下各方法及优缺点. 方法一 锚点定位 ? 1 <a href="#" class ...
- bootstrap timepicker 在angular中取值赋值 并转化为时间戳
上一篇我们讲到angular对于timepicker的一个封装后的插件angular-bootstrap-timepicker,但是由于angular的版本必须是v1.2.30以上的.对于有些涉及到多 ...
- IO学习一(File类)
File类 1.凡是与输入.输出相关的类.接口都定义在java.io包下 2.File有构造器来创建对象,此对象对应着一个文件或文件目录 支持文件类型:.txt .avi .doc .jpg .ppt ...
- js 从一个对象中找到属性值相等的集合
getobjs: function(objs, key, value) { var result = []; for (var i in objs) { var obj = $(objs[i]); i ...
- es6 语法 (map、set和obj 的对比)
//数据结构对比 增查改删 { //map.set和Object let item = {t:1}; let map = new Map(); let set = new Set(); let obj ...
- [HTML/CSS]创建新元素的三种方法
第一种:通过text/HTML var txt1="<h1>Text.</h1>"; 第二种:通过jQuery var txt2=$("<h ...