LOJ#6756. 随机数生成器
给定 (n,k),表示有 (n) 个初始为 (0) 的变量,操作 (k) 次,每次随机给一个数 (+1),求最大值的期望。
- subtask1 (kle 2400,nle 400)
- subtask2 (kle 5cdot 10^4,nle 20)
Solution
有幸在 LOJ 上放了一道题,当然要来水题解啦。(虽然这个题的做法是 EI 鸽鸽教导我的。)
subtask1 就是容斥一下可以得到一个调和级数的系数,或者直接 min-max 反演也可以,然后就可以 (mathcal O(k^2ln k)) 的递推了。
subtask2 的话大概基于以下的分析:
设 (F_z(x)=sum_j [jle z]frac{x^j}{j!}),那么我们可以在 (mathcal O(nk)) 的复杂度计算 (F_z(x)^n)(求导 + 递推)
我们需要求的是为 (z=1,2...k) 计算 (F_z(x)^n[x^k])
考虑分块,我们每隔 (cnt) 个位置设置一个关键点,设当前考虑到的关键点为 (m)
我们先计算出 (F_m(x)^n),并以此为基础考虑 (F_{m+t}(x)^n[x^k])
可以注意到:(F_{m+t}(x)=F_m(x)+A(x))
故:
我们可以发现 (A(x)^j) 的最低次幂为 (j imes (m+1)),所以当 (j> frac{k}{m}) 时我们就不需要求了。
只需要为 (A(x)) 计算前 (1,2,3...frac{k}{m}) 项。
这个可以求导 + 递推处理,复杂度 (mathcal O(frac{k^2}{m}))
然而这样太暴力了,可以观察到,(A(x)^j) 只有 (tj) 项。
我们只枚举这 (tj) 项就可以将这个部分的复杂度降低为 (mathcal O(t imes frac{k^2}{m^2}))
事实上,由于我们最多只需要计算前 (n) 次幂,所以为一个 (t) 进行计算的复杂度为 (mathcal O(t imes min(frac{k}{m},n)^2))
tips: 于是我们只需要预处理 (F_m(x)^1,F_m(x)^2...F_m(x)^n)
于是我们如果每隔 (cnt) 个位置设置关键点,那么我们会设置 (frac{k}{cnt}) 个关键点,为每个关键点预处理的复杂度为 (mathcal O(nk)),这个部分的复杂度为 (mathcal O(nfrac{k^2}{cnt}))
接下来考虑为每个关键点计算 (m+t) 处的答案的复杂度,单点计算的复杂度为 (t imes min(n,frac{k}{m})^2),总复杂度为 (min (frac{k}{m},n)^2 imes cnt^2)
方便起见设 (m=rcdot cnt),于是当 (rcdot cntle frac{k}{n}) 时,单次计算的复杂度为 (n^2 imes cnt^2),这个部分需要计算 (frac{k}{ncdot cnt}) 次,复杂度为 (mathcal O(nkcdot cnt))
当 (rcdot cntge frac{k}{n}) 时,单次计算的复杂度为 (mathcal O(frac{k^2}{r^2})),这个部分的复杂度和为:
于是总体复杂度为 (mathcal O(nkcdot cnt+frac{nk^2}{cnt})),取 (cnt=sqrt{k}) 可以得到最优复杂度为 (mathcal O(nk^{1.5}))
如果追求更优的理论复杂度,可以将 (nk) 递推的部分全部换成 (ln+exp),再通过对小部分的暴力来均摊复杂度,可以得到 (mathcal O( extrm{poly}~ k^{frac{5}{3}}))