概率与期望
概率
概率
事件发生的可能性大小即为概率,事件 \(A\) 发生的概率用 \(P(A)\) 表示。
条件概率
在事件 \(B\) 发生的前提下,事件 \(A\) 发生的概率即为条件概率,用 \(P(A|B)\) 表示,\(P(A|B)\) 定义为:
若 \(P(A|B)=P(A)\),则称 \(A\) 与 \(B\) 相互独立。此时 \(P(A\cap B)=P(A)P(B)\)。
全概率
设事件 \(B_i\) 构成一个完备事件组(两两互斥且覆盖所有可能)。那么对于任意事件 \(A\),全概率公式为:
期望
直觉上看,如果重复一个随机实验无数次,观察到的平均值会趋近于期望值。
设离散型随机变量 \(X\) 的概率分布为 \(p_i=P(X=x_i)\),则期望:
性质
对于任意随机变量 \(X,Y\),无论是否独立,给定常数 \(a,b\),有:
对于相互独立的随机变量 \(X,Y\),有:
全期望
如果事件 \(A_i\) 构成一个完备事件组(即互斥且覆盖所有情况),则:
题目
UVA11181 条件概率 Probability|Given
题意:
共有 \(n\) 个随机变量 \(x\),其中 \(x\in\{0,1\}\),已知 \(x=1\) 的概率为 \(p_i\),且 \(\sum\limits_{i=1}^nx_i=m\),求每个变量 \(x_i=1\) 的概率。
根据条件概率,设事件 \(B\) 表示 \(\sum\limits_{i=1}^nx_i=m\),事件 \(A_i\) 表示 \(x_i=1\),则有:
其中 \(P(A_i\cap B)\) 表示 \(x_i=1\) 且 \(\sum\limits_{i=1}^nx_i=m\),即 \(x_i=1,\sum\limits_{j\in[1,n],j\ne i}x_i=m-1\)。
先来考虑 \(P(B)\) 怎么求,可以设 \(f_{i,j}\) 表示 \(\sum\limits_{k=1}^{i-1}x_k=j\) 的概率,转移方程:
则 \(P(B)=f_{n,m}\)。
对于 \(P(A_i\cap B)\),可以把变量从 \(i\) 处分开,分别求答案后相乘,具体地:
设 \(g_{i,j}\) 表示 \(\sum\limits_{k=i+1}^{n}x_k=j\) 的概率,转移方程与 \(f\) 同理:
于是就可以得到 \(P(A_i\cap B)\):
减 \(1\) 和乘 \(p_i\) 是因为 \(x_i\) 需要被选择。
实现是简单的。
CF1097D Makoto and a Blackboard
题意:
给定一个正整数 \(n\),共进行 \(k\) 次操作,对于每次操作,设 \(d\mid n\),令 \(n\leftarrow d\),每种合法的 \(d\) 的选择是等概率的,求 \(k\) 次操作后 \(n\) 的期望。
看到操作是和约数相关的,首先想到分解质因数,不难发现操作对每个质因子是独立的。所以:
\(x_i\) 表示 \(k\) 次操作后质因子 \(p_i\) 的指数。
设 \(dp_{t,i}\) 表示经过 \(t\) 次操作后,指数变为 \(i\) 的概率,则 \(dp_{0,c}=1\),\(c\) 为初始指数。设当前枚举指数 \(i\),有转移方程:
除法可以预处理逆元。
经过 \(k\) 次操作后,该质因子对答案的期望贡献为:
实现
考虑对 dp 数组压维。
#include <bits/stdc++.h>
using namespace std;
#define int long long
const int N = 1e4 + 5, M = 4e7 + 5, mod = 1e9 + 7;
int n, k, top, dp[N], inv[N], t[N];
bool nprime[M];
vector <int> primes;
pair <int, int> p[N];
int qpow(int a, int b){
int res = 1;
while (b){
if (b & 1){
(res *= a) %= mod;
}
(a *= a) %= mod;
b >>= 1;
}
return res;
}
void init(int n){
for (int i = 2; i <= n; ++i){
if (!nprime[i]){
primes.push_back(i);
}
for (auto p : primes){
if (p * i > n)break;
nprime[p * i] = 1;
if (i % p == 0)break;
}
}
}
signed main(){
cin.tie(0)->sync_with_stdio(0);
cin >> n >> k;
init(sqrt(n));
for (auto m : primes){
if (n % m == 0){
p[++top] = {m, 1};
n /= m;
while (n % m == 0){
++p[top].second;
n /= m;
}
}
}
if (n > 1){
p[++top] = {n, 1};
}
for (int i = 1; i <= N - 5; ++i){
inv[i] = qpow(i, mod - 2);
}
int ans = 1;
for (int i = 1; i <= top; ++i){
memset(dp, 0, sizeof dp);
dp[p[i].second] = 1;
for (int j = 1; j <= k; ++j){
memset(t, 0, sizeof t);
for (int l = 0; l <= p[i].second; ++l){
if (dp[l] == 0)continue;
for (int r = 0; r <= l; ++r){
t[r] = (t[r] + dp[l] * inv[l + 1]) % mod;
}
}
for (int j = 0; j <= p[i].second; ++j){
dp[j] = t[j];
}
}
int res = 0, s = 1;
for (int j = 0; j <= p[i].second; ++j){
res = (res + dp[j] * s) % mod;
s = s * p[i].first % mod;
}
(ans *= res) %= mod;
}
cout << ans;
return 0;
}

浙公网安备 33010602011771号