LG-P3779 [SDOI2017] 龙与地下城 Solution

更好的阅读体验戳此进入

题面

给定一个 m 面的骰子,等概率产出 0,1,2,,m1,投 n 次,求投出来的数之和在区间 [A,B] 的概率。

Solution

首先介绍一点前置知识:

正态分布:图形不再赘述,唯一需要注意的就是随机变量 X 的正态分布只需要它的期望 μ 和方差 σ2 即可描述,记作 N(μ,σ2),不难发现这恰好对应着题干。

概率密度函数:依然考虑一个随机变量 X,若其为离散的那么显然可以简单的求出任意点的概率。但若其为连续型的,那么一个点的概率在极限意义下为 0,然然而查询一段区间的时候显然不为 0,所以我们便引入了概率密度函数来描述这个概率,对于随机变量 X 的概率密度函数 f(x),需要满足 f(x) 在区间内的积分等于 X 落在该区间的概率。

然后有个结论:正态分布的概率密度函数为:

f(x)=12πσ2e(xμ)22σ2

关于这个东西的证明。。。完全不是人看的,似乎只能强行记下来这个公式。。。如果你一定要看一下证明,网上倒是也有一个 正态分布推导过程

然后还有就是 C++ 库里自带了个 erferfc,大概求的是误差函数的积分和互补误差函数之类的,(我不会),有兴趣可以看看。

然后所以如果我们能够证明本题这玩意是正态分布的,那么就直接对这个 f(x) 做自适应辛普森,求一下积分就行了。

独立同分布:首先独立比较好理解,就是两个随机变量之间无影响,和高中数学里面的独立事件差不多。然后同分布就是指一些随机变量服从相同的分布。

Tips:概率论中 E(X) 表示期望,D(X) 表示方差。

中心极限定理:对于 n 个独立同分布(如本题中的相同骰子)的随机变量 X1,X2,,Xn,若 E(Xi)=μ,D(Xi)=σ2,令:

Yn=i=1nXinμnσ2

n 足够大,则我们认为 YnN(0,1)

然后还有一个常用推论,当然首先我们需要知道正态分布的一点运算规则,即:

XN(a,b)cXN(ca,c2b),从期望和方差的意义不难理解。

XN(a,b)X+cN(a+c,b),同理不难得出。

所以我们可以将刚才的中心极限定理式子转化为:

i=1nXiN(nμ,nσ2)

也就是说,本题里求的这些骰子的点数和,实际上就是 n 个独立同分布的和,所以一定服从 N(nμ,nσ2),用我们刚才写的正态分布概率密度函数带进去这个期望和方差然后求个积分即可。

然后发现这东西套个自适应辛普森就可以在 O(玄学) 的复杂度完成。

但是我们不难发现这个东西还有点问题,就是中心极限定理需要一个前提,n 足够大,对于一些 n=1 之类的数据点用这个就显然寄了,所以我们要考虑一些数据点分治的做法。

显然对于 n 较小的数据,我们可以考虑多项式,多项式 i 次方项的系数为骰子值为 i 的概率,显然当 n=1 时,假设骰子面数为 m,不难想到多项式为 1mxm1+1mxm2++1mx1+1mx0。然后很容易想到对于其它的 n 结果就是这个多项式的 n 次方,我们只需要用 FFT 优化一下然后在结果里求出指数在 [A,B] 之间的系数和即可,这东西可以用多项式快速幂优化(这个实际上不算是多项式快速幂,因为最终多项式总长度较小,所以在正常 FFT 时写个复数的快速幂就行),我们可以分析一下,显然多项式初始项数最多为 m,所以时间复杂度大概是 O(nmlognm),常数不小,然后 nm4e6 级别的,总之 nm1e5 应该不成问题,而且因为我们的中心极限定理一般要求 n30 就可以了,所以这个理论上就可以过了。

Tips:仅用多项式快速幂期望得分 60~70。

upd:上述过程就可以通过本题了,需要注意的一个问题是不要忘记在自适应辛普森的过程中限制层数,后文是我最开始写这道题时的因为没有限制层数的一些误区与另一种类似的方法,仅供参考。


如果不在自适应辛普森中限制层数,那么会有精度问题,原因除此之外还可能因拟合 N(0,1) 的概率密度函数会比拟合 N(nμ,nσ2) 精度更高一点,可能因为 nμnσ2 的值域范围太大了,再加上自适应辛普森本来精度就很玄学,所以会导致最终答案精度爆炸。

总之还可以考虑另一个方法,即中心极限定理的初始式子:

Yn=i=1nXinμnσ2

不难发现我们知道了限定的 i=1nXi 的范围,也就可以带进式子里直接推出 Yn 的范围,然后用自适应辛普森跑一下 N(0,1) 的概率密度函数,因为 YnN(0,1),所以求出对应范围之后直接求 N(0,1) 的概率密度函数在新范围里的积分即为答案。不过这样会发现依然是错误的如果在自适应辛普森中限制层数那么就没有问题了。

检查发现,对于正态分布中,在角落可能很小,从而导致 [l,mid],[mid,r],[l,r] 都很小,从而直接返回 0,可以感性理解一下,所以可能会导致拟合的误差过大,于是考虑每次求范围 [A,B] 的时候分别拟合 [0,A][0,B],然后用 [0,B] 的值减去 [0,A] 的,这样是等效的,且会更多的引入较大的值使得精度更高,改成此方法后即使不限制层数也可以通过本题。

Tips:代码中注释部分即为后半部分的实现方式。

Code

UPD

update-2022_12_10 初稿

update-2023_02_01 fix 初稿中的一些错误与不严谨的表述