【随笔】计算等比数列求和
真的是随笔。。
等比数列求和大家都知道,就是求 \(\sum_{i=0}^nq^i\)。一般来说我们都会对 \(p\) 取模。
下面我们来讨论如何快速地求这个值。暴力 \(O(n)\) 做就算了吧。
经典方法
小学生都知道,\(\sum_{i=0}^nq^i=\dfrac{q^{n+1}-1}{q-1}\)。证明也是小学生都会的错位相消。
那么我们求一下快速幂,求出 \(q-1\) 在 \(\bmod p\) 意义下的逆元,乘起来就行了。
遗憾的是,某些出题人并没有这么良心。如果 \(p\) 不是质数,\(q-1\) 在 \(\bmod p\) 意义下的逆元就不存在了>_<
因此,这个方法的要求就是:\(p\) 为质数。当然如果题目告诉你 \(\gcd(q-1,p)=1\) 也可以,不过一般没人这么干。
不知道算什么的算法
若 \(2\mid n\):
\[\sum_{i=0}^nq^i=\sum_{i=0}^{n/2}q^i+\sum_{i=n/2}^nq^i-q^{n/2}=\sum_{i=0}^{n/2}q^i\cdot(1+q^{n/2})-q^{n/2}
\]
若 \(2\nmid n\):
\[\sum_{i=0}^nq^i=\sum_{i=0}^{(n-1)/2}q^i+\sum_{i=(n+1)/2}^{n}q^i=\sum_{i=0}^{(n-1)/2}q^i\cdot(1+q^{(n+1)/2})
\]
因此,不管怎样,问题的规模都会被我们缩减一半。
结合快速幂,在计算的同时算出 \(q^{n/2}\) 或者 \(q^{(n+1)/2}\) 的值,即可做到 \(O(\log n)\)。
矩阵快速幂加速递推
不难写出整式递推:记 \(S_n=\sum_{i=0}^nq^i\),则有 \(S_n=qS_{n-1}+1,S_0=1\)。写成矩阵:
\[\begin{bmatrix}S_{n+1}&1\end{bmatrix}=\begin{bmatrix}S_n&1\end{bmatrix}\times\begin{bmatrix}q&1\\0&1\end{bmatrix}
\]
矩阵快速幂即可。\(O(\log n)\)。