【题解】CF1479E School Clubs
CF1479E 题解
前置知识:鞅与停时定理
鞅
我们有一个随机过程 \(X_0,X_1, ...\)。如果 \(\forall n \in \mathbb N, \ E(Y_n) < \infty\) 且 \(\forall n \in \mathbb N^+, \ E(Y_{n + 1}|X_n,X_{n-1},...,X_0) = E(Y_n)\),则我们称 \(Y_0, Y_1, ...\) 为该随机过程的鞅。
离散时间鞅
如果随机过程 \(X_0,X_1, ...\) 满足 \(\forall n \in \mathbb N, \ E(X_n) < \infty\) 且 \(\forall n \in \mathbb N^+, \ E(X_{n + 1}|X_n,X_{n-1},...,X_0) = E(X_n)\),则我们称该随机过程为离散时间鞅。
即:已知之前所有的过程,之后的观察值的期望等于之前的观察值的期望
停时定理
对于一个随机过程,如果我们可以根据之前的过程判断该过程是否已经停止(即不用知道未来的过程),则他的停时为一个随机变量 \(\tau\)。
如果满足下列几个条件之一,则我们有 \(E(X_\tau) = X_0\)。
- \(\tau\) 几乎一定有界
- \(|X_{t + 1} - X_t|\) 一致有界,且 \(E(\tau)\) 有限
- \(X_t\) 一致有界,且 \(\tau\) 几乎一定有限
注意,这里由于 \(\tau\) 不是一个定值,所以和前面说的离散时间鞅的定义不同。
读者自证不难
OI里面怎么用
有随机过程 \(A_0, A_1, ...\),考虑构造势能函数 \(\phi\)。要求 \(E(\phi(A_{t+1}) - \phi(A_t) | A_t, A_{t-1}, ..., A_0) = -1\)。
则我们构造随机过程 \(X_t = \phi(A_t) + t\),易证 \(X_0, X_1, ...\) 为离散时间鞅。
停时定理,\(E(X_\tau) = X_0\) 即 \(E(\phi(A_\tau) + \tau) = \phi(A_0)\),则 \(E(\tau) = \phi(A_0) - \phi(A_\tau)\)。
CF1479E School Clubs
Statement
有 \(n\) 个学生和 \(m\) 个组,每个人在一个组里面,第 \(i\) 个组的人数为 \(a_i\)。
现在,每天有一个学生(\(n\) 个学生中随机的一个)会生气,他会:
- 有一半的概率他会脱离这个组,并且成立一个新的组。
- 有一半的概率他会脱离这个组,并且进入一个已经成立的组。他进入第 \(i\) 个组的概率为 \(\frac {a_i} n\),他可能会回到原来的组。
求第一次出现所有学生在同一个组的期望天数。
\(m \le 1000\),\(n \le 4 \times 10^8\)
Sol
在这道题中,我们可以用一个可重集来描述状态,然后我们考虑如何设计 \(\phi\)。
由于不同组之间是独立的,所以我们可以分开计算其势能,即 \(\phi(A_t) = \sum _{a \in A_t} f(a)\)。
分类讨论
-
操作 1,有一个人离开了一个组,进入了一个新的组。则
\[\phi(A_{t + 1}) = \phi(A_t) - f(a_x) + f(a_x - 1) + f(1) \] -
操作 2,回到原来组。则
\[\phi(A_{t + 1}) = \phi(A_t) \] -
操作 2,没有回到原来组,则
\[\phi(A_{t + 1}) = \phi(A_t) - f(a_x) + f(a_x - 1) - f(a_y) + f(a_y + 1) \]
综上
根据势能函数需要满足的要求
所以
由于 \(a_i=0\) 是不会产生贡献的(因为你永远不可能动他)所以相当于扔掉了,因此势能为 0,即 \(f(0) = 0\)。
因为我们关心的是势能的差,所以为了方便我们取 \(f(1)=-2\),把常数项消掉。则
算法一
由于 \(E(A_\tau) = f(n)\),所以 \(E(\tau) = E(A_0) - E(A_\tau) = \sum f(a_i) - f(n)\)。
线性暴力计算。
这个怎么能过???
CF 机子太快了!!1
算法二
刚才那个柿子也可以变成这样
则我们记 \(f(a)\) 的差分 \(g(a)=f(a+1)-f(a)\),有
而因为 \(f(0)=0\),\(f(1)=-2\),所以 \(g(1)=-2\)。
然后就是考虑怎么求
有一个很巧妙的 trick。\(N\) 是一个比 \(a\) 大的数。令
考虑分块求解,块长 \(B = \sqrt N\),则令
则
接下来考虑如何计算。
对于 \(R(z)\),首先 \(R(0)\) 是可以 \(O(\sqrt n)\) 计算的。
考虑递推
求出 \(R(0) .. R(B)\) 之后我们进行插值,就可以得到多项式 \(R(z)\)。然后我们可以多点求值求出所有 \(R(Bi)\)。
对于剩余的部分,我们需要求的其实是一些 \(2n-x\) 或者 \(n-x\) 的前缀或者后缀积。
我们考虑如何求一个一次函数 \(F(x)\) 的前缀积。(后缀积不说了,因为可以很方便地转化成前缀积)
我们延续前面的分块的思想。记 \(D(z) = \prod _{i=z+1}^{z+B} F(i)\)。
注意到 \(D(z)\) 是一个关于 \(x\) 的 \(B\) 次多项式,所以我们延续前面求 \(R(z)\) 的想法,先求出 \(D(0) , D(1), \cdots, D(B)\) 然后插值、多点求值求出所有的 \(D(Bi)\)。
这么做的时间复杂度是 \(\mathcal O(\sqrt n(m + \log^2 N))\)。
算法三
快速插值和多点求值常数太大辣!!!
其实我们可以用“快速阶乘”的 trick 去掉一个 log。
首先我们有多项式 \(f(x)\) 和若干个点值 \((x_i, f(x_i))\)。考虑拉格朗日插值的公式
在这个问题中 \(x_i\) 分别为 \(0\) 到 \(d\)。所以
考虑怎么求 \(f(d + k)\),\(1 \le k \le t\)
括号里面可以卷积计算:
故
如果给出 \(f(0), f(B), f(2B), .. f(Bk)\),要求 \(f(d), f(d+B), .., f(d+Bk)\),则设 \(g(x) = f(Bx)\) 就可以解决。
接下来考虑如何求 \(R(z)\)。
那么我们要算的就是 \(P(0, B), P(s, B), ... , P(sB, B)\),\(R, Q\) 同理。
如何递归计算?
我们发现,我们需要计算的其实是:
\(P(0 + ks, B)\),\(P(B + ks, B)\),\(P(sB + ks, B)\),\(P(B + sB + ks, B)\),其中 \(0 \leq k \leq B\);
那么我们使用前面给出的方法容易由第一组 \(P\) 算出其他三组。
然后就可以使用倍增求解。时间复杂度 \(T(k) = T(k / 2) + O(k \log k) = O(k \log k)\),其中 \(k\) 为多项式的次数。
这种方法的时间复杂度是 \(\mathcal O(\sqrt n(m + \log N))\),比算法二少了一个 log,常数也由显著提升(因为不用多点求值)
总结
这道题是一道好题。
对于求停时期望的问题,构造势能函数、使用停时定理是一种非常好的解决问题的方法。
算法一考察了选手胆大心细的能力以及对CF评测机的了解程度(bushi)。
算法二考察了对于一类多项式的类似阶乘的形式的问题,使用分块求解的方法。
算法三考察了对于拉格朗日插值公式的变形,在此类问题中把多点求值问题转化成标准的卷积性质的方法。
代码
翻cf递交记录吧。