AGC032F One Third

很奇怪的一个题。看见了无从下手。概率期望好题。


UPD

涨了姿势之后,发现下面连续概率的式子表述有很大的问题。

关于改呢……不知道要鸽到什么时候了。

但是貌似不太影响理解。


给一个面积为 \(1\) 的圆,经过圆心随机幅角切直径 \(n\) 次,定义 \(f(x) = \min |S - \frac{1}{3}|\),其中 \(S\) 是连续块面积。求 \(f(x)\) 期望。

目前见到了两种做法。

首先开始的转化都是一样的。

因为答案是连续段,只和选出两个向量有关。考虑计算答案的式子(其中面积模 \(1\)):

\[\min \left\{|x - y \pm \frac{1}{3}|\right\} \]

\(\pm\) 也就是对于两个互补的块都算一遍。于是过直径的切口可以直接当做一个从圆心出发的向量。类似复平面的单位向量。

我们把后面的 \(-y \pm \frac{1}{3}\) 提出来,也就是将 \(y\) 乘上个三次单位根的幂。

所以不如把每个向量变为 \(\left\{v, v \times \omega_3^1,v \times \omega_3^2\right\}\),然后求 \(x - y\) 幅角模 \(\frac{4\pi}{3}\) 最小值。

显然会出问题,因为当乘的单位根相同的时候,答案就假了,变为原式中 \(|x - y|\),但是单位根不同时都是行的,所以我们把扩展出的向量染色。

例如,\(\left[v, v \times \omega_3^1,v \times \omega_3^2\right]\),分别对应 \(\left[\texttt{red}, \texttt{green}, \texttt{blue}\right]\)(RGB)。

那么问题转化为求异色幅角差最小值。

显然答案小于 \(\frac{1}{3}\),且异色向量对之间不会有其他向量(即贪心地只取相邻的贡献到答案上)

显然如果选定一个向量为基准,它将单位圆分成的三个部分可以通过一个颜色的置换互相得到,所以只要算 \(\left[0, \frac{1}{3}\right)\) 即可。

问题变为,左端为红色,右端为绿色,长度为 \(\frac{1}{3}\),中间撒任意颜色 \(n - 1\) 个点,\(n\) 个异色段中长度差最小值期望。


首先来一个结论:

长度为 \(1\),分成 \(n\) 段,那么长度最小值的期望为 \(\frac{1}{n^2}\)

简单证明一下。

考虑计算 \(P\left(\min = x\right) x\) 的积分,即 \(P\left(\min \geq x \right)\) 的积分。(前面那个我不会算 \(P\),我算出来都是错的 QAQ)

考虑 \(P\left(\min \geq x \right)\), 我们将每一段丢掉 \(x\),剩下随便选,那么 \(P\left(\min \geq x \right) = \left( 1 - nx \right) ^ {n-1}\)

积分一下即可证明。

下面有两个方法

直接上组合方法

容易求出 \(k\) 个异色段的最小值期望: \(\frac{1}{3} \times \frac{k}{n} \times \frac{1}{k^2} = \frac{1}{3nk}\)

那么只要求出 \(k\) 个异色段的概率即可。

我们只要 DP 出有 \(k\) 个异色段,第一个颜色为红最后一个颜色为绿的概率。直接 \(dp\) 起来有点慢,可以直接组合数枚举哪些地方颜色发生了变化,所以可以直接 DP 相邻两个颜色都不同的概率即可。只要枚举下一个颜色是什么, \(O\left(n\right)\) 完成计算。

显然答案可以通过枚举 \(k\),算期望乘以概率的和得到。

概率方法

考虑将得到的线段长度由小到大排序,如果最小的异色段是第 \(k\) 小,那么前面 \(k - 1\) 个都是同色的。

扩展一下上面的结论,我们枚举第 \(k\) 小。现在要得到第 \(k\) 小的长度期望。同样考虑丢掉一段,可得递推式:

\[E_k = \frac{1 - \sum_{i=1}^{k-1} \left(n - i + 1\right) E_i}{k^2} + \sum_{i=1}^{k-1} E_i \]

通过手算前几项,加上猜测以及归纳,可以得到

\[E_k = \frac{1}{n} \sum_{i=1}^{k} \frac{1}{n - i + 1} \]

现在要算 \(P\left( \min = k \right)\),但是乘上这个 \(E_k\) 式子有点不优美。

所以改成算 \(P\left( \min \geq k \right)\),然后对 \(\min \geq k\) 贡献上去 \(\frac{1}{n} \times \frac{1}{n - k + 1}\)

显然这样求和答案不变。而且 \(P\left( \min \geq k \right)\) 也十分好算。因为至少有 \(k - 1\) 个段是相同的。虽然看起来有很多首尾相接的线段,使得概率互相关联使得算这个看起来很毒瘤,但是冷静思考可以发现,对于首尾拼接的 \(L\) 个段,它 \(L+ 1\) 个点全部同色的概率为 \(\left(\frac{1}{3}\right)^{L}\),因为最左端的点不论是否确定对答案都没影响。

废话了那么多,其实就是 \(P\left( \min \geq k \right) = \left(\frac{1}{3}\right)^{k - 1}\)

那么答案就是

\[\begin{align*} E & = \frac{1}{3} \sum_{i=1}^{n} P(i) E_i \\ & = \frac{1}{n} \sum_{i=1}^{n} \frac{1}{3^{i} \left(n - i + 1\right)} \end{align*} \]

显然可以 \(O\left(n\right)\) 计算。

代码很简单,很不错的一道题。可以推广到 \(\frac{1}{k}\)

#include <bits/stdc++.h>

const int mod = 1000000007;
const int inv3 = (mod + 1) / 3;
typedef long long LL;
void reduce(int & x) { x += x >> 31 & mod; }
int mul(int a, int b) { return (LL) a * b % mod; }
int fastpow(int a, int b, int res = 1) {
	for (; b; b >>= 1, a = mul(a, a)) if (b & 1) res = mul(res, a);
	return res;
}

const int MAXN = 1000010;
int inv[MAXN], n;
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	std::cin >> n;
	*inv = inv[1] = 1;
	for (int i = 2; i <= n; ++i)
		inv[i] = mul(inv[mod % i], mod - mod / i);
	int ans = 0, now = 1;
	for (int i = 1; i <= n; ++i) {
		now = mul(now, inv3);
		reduce(ans += mul(inv[n - i + 1], now) - mod);
	}
	std::cout << fastpow(n, mod - 2, ans) << '\n';
	return 0;
}


如果式子有错误请留言

感谢 @ccosi @猪了个去 的文章

posted @ 2019-10-21 17:00  daklqw  阅读(518)  评论(1编辑  收藏  举报