BZOJ1485 [HNOI2009]有趣的数列
洛谷上很多省选题都没有题解,不得不找
bzoj
的题解
概述
50%
使用递推,在$\mathcal O(n^2)$的时间内得到答案,不过我没写对。
正解
通过暴力或者上述方法,打印出较小的答案,可能会发现规律。实际上这题就是求Catalan数
(n-2),有很多理解方式,常见的求法有三种(参见百度百科 ):
- $f_n=\sum\limits_{i=0}^{n-1}f_i*f_{n-i-1}$ ,不能使用这个公式,因为也需要$\mathcal O(n^2)$
- $f_n=f_{n-1}*\frac{4n-2}{n+1}$ ,我本来以为可以用的,但是由于$p$不一定是一个质数,因此无法计算逆元以进行除法运算
- $f_n=\frac{\mathcal C_{2n}^{n}}{n+1}$ ,这是可用的公式
如果不熟悉组合数的求法,可以做一下计算系数 ,总结中给出代码。
其中$\frac{\mathcal C_{2n}^{n}}{n+1}=\frac{\prod\limits_{i=n+2}^{2n}i}{\prod\limits_{i=1}^ni}$,我们需要把所有$2n$之内的质数筛出来,同时得到每个数最小的质因数(欧拉线性筛法),进行约分再使用快速幂1得出结果。
代码
1 |
|
总结
组合数相关
这题需要求组合数,我总结了一下我知道的组合数取模的求法(P1313模板):
- 使用杨辉三角$\mathcal C_n^0=\mathcal C_n^n=1$ ,$\mathcal C_n^i=\mathcal C_{n-1}^i+\mathcal C_{n-1}^{i-1}$ 代码见这里
- 当$p$是质数时可以得出$a$的逆元为$a^{p-2}$ ,$\mathcal C_n^0=1$ ,$\mathcal C_n^i=\mathcal C_n^{i-1}\frac{k-i+1}{i}$ 代码见这里
- 当$p$不是质数时只能用上述方法,筛出质数并约分代码见这里
应该不需要解释吧
时间复杂度分析
在添加数时,也可以先把这个数分解,但应该会降低效率.
而我用的方法筛质数、添加数、向下传递都是$\mathcal O(n)$的,最后一步为$\pi(n)\log n$ 2,而$\pi(n)\sim\frac{n}{\ln n}$ ,因此也近似于$\mathcal O(n)$ .