zoukankan      html  css  js  c++  java
  • 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}| ight} ]

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

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

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

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

    例如,(left[v, v imes omega_3^1,v imes omega_3^2 ight]),分别对应 (left[ exttt{red}, exttt{green}, exttt{blue} ight])(RGB)。

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

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

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

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


    首先来一个结论:

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

    简单证明一下。

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

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

    积分一下即可证明。

    下面有两个方法

    直接上组合方法

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

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

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

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

    概率方法

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

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

    [E_k = frac{1 - sum_{i=1}^{k-1} left(n - i + 1 ight) 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} ]

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

    所以改成算 (Pleft( min geq k ight)),然后对 (min geq k) 贡献上去 (frac{1}{n} imes frac{1}{n - k + 1})

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

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

    那么答案就是

    [egin{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 ight)} end{align*} ]

    显然可以 (Oleft(n ight)) 计算。

    代码很简单,很不错的一道题。可以推广到 (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) << '
    ';
    	return 0;
    }
    
    

    如果式子有错误请留言

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

  • 相关阅读:
    2014年终总结
    杭电2014——青年歌手大奖赛_评委会打分
    nyoj---t448(寻找最大数)
    nyoj_t218(Dinner)
    将string转换成char*
    nyoj71--独木舟上的旅行
    基于贪心算法的几类区间覆盖问题
    会场安排问题—NYOJ14
    南阳理工ACM——106背包问题
    南阳理工91——阶乘之和
  • 原文地址:https://www.cnblogs.com/daklqw/p/11714581.html
Copyright © 2011-2022 走看看