0
点赞
收藏
分享

微信扫一扫

“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)


​​题目传送门​​

“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_ios

题解

  • 我们要求的是一个条件概率:在事件B(:至少m个反面)发生的情况下,求事件A(:恰好k个正面)发生的概率。
  • 即求条件概率“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_条件概率_02,由条件概率公式得:“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_ios_03
  • “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_ios_04实际上就是P(A),所以所求变成了“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_条件概率_05
  • “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_样本空间_06
  • “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_概率论_07
  • 那么最后我们得到“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_ios_08
  • “科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_样本空间_09我们可以直接根据公式计算:“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_概率论_10
  • 那么我们只需要预处理一下阶乘数组即可。
  • 但是这样会超时,注意数据范围“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_条件概率_11
  • 实际上,“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_ios_12的分子“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_条件概率_13可以转化为:“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_ios_14。这样就可以了
  • 注意一下乘法逆元即可。
  • 其实条件概率还有另一种计算方式:在缩小样本空间内计算:“科林明伦杯”哈尔滨理工大学第十届程序设计竞赛——D.扔硬币【条件概率 & 乘法逆元】(附条件概率推导过程)_条件概率_15,这种方法的计算结果就是上述推导最后得到的结果。

AC-Code

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAXN = 1e5 + 7;
const int mod = 1e9 + 7;

ll q_pow(ll a, ll b, ll mod) { // 快速幂
ll res = 1LL;
while (b) {
if (b & 1) res = (res * a) % mod;
a = (a * a) % mod;
b >>= 1;
}
return res % mod;
}

ll inv(ll x) {
return q_pow(x, mod - 2, mod);
}

ll factorial[MAXN] = { 1 }; // 阶乘

inline ll C(ll n, ll k) {
return factorial[n] * inv(factorial[n - k] * factorial[k]%mod) % mod;
}

int main() {
std::ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
factorial[0] = 1;
for (int i = 1; i <= MAXN - 7; ++i)
factorial[i] = factorial[i - 1] * i % mod;;
int t; cin >> t;
while (t--) {
ll n, m, k; cin >> n >> m >> k;
if (k + m > n) {
cout << 0 << endl;
continue;
}
ll a = C(n, k), b = q_pow(2, n, mod);
for (int i = 0; i < m; ++i)
b = (b - C(n, i) + mod) % mod;
cout << a * inv(b) % mod << endl;
}
}


举报

相关推荐

0 条评论