简介:《等差、等比数列公式总结.pdf》是一份面向高中数学学习者与备考者的公式速查手册,系统梳理了等差数列与等比数列的定义、通项公式及变式、前n项和公式、几何意义、常用性质,并给出两类数列的类比对照,帮助读者快速建立知识框架。等差中项、等比中项、片段和等典型性质以及分组求和、裂项相消、错位相减等常见求和方法也均有涉及,从基础定义到进阶变式逐层梳理,重点公式以条目化呈现,便于对照记忆和快速定位,适合在课后巩固、考前冲刺或解题时随时查阅。资源仅包含1个PDF文档,压缩包约193KB,轻量易用,可打印或放入移动设备离线查看。目前已有408人学习下载,是一份简洁实用的数列公式总结,能有效节省整理笔记的时间。
1. 从算法复杂度题反推等差数列公式的用途
第一次把等差等比公式当回事,不是在数学课上,而是在分析一段"二分+暴力"的代码复杂度时:外层循环跑 $n$ 轮,内层每轮迭代次数递减,总迭代次数恰好是 $1+2+\dots+n$;另一段递归的调用次数呈 $1+q+q^2+\dots$ 的形状。没有公式只能写循环硬加,有了公式直接 O(1) 出结果。这份《等差、等比数列公式总结》PDF 把定义、通项、变式、前 n 项和、性质以及分组求和、裂项求和、错位相减三种套路压缩在一份速查讲义里。适合三类人:需要系统梳理公式推导逻辑的学生、要给学生出题或讲题的老师,以及在代码里想用封闭式替代循环累加的开发者。下文直接按"公式拆解→代码复现→边界处理"的顺序把这套内容过一遍。
2. 等差数列:通项变形、前n项和与直线模型的对应
2.1 定义与通项公式的三种写法
等差数列的定义写作 $a_{n+1}-a_n=d$,其中 $d$ 是公差。这个递推式在程序里就是一个a += d的循环。通项公式 $a_n=a_1+(n-1)d$ 表达的是一次线性关系:以 $n$ 为自变量,$a_n$ 是一条斜率为 $d$ 的直线。讲义里给的变式 $a_n=a_m+(n-m)d$ 更实用,它允许从任意已知项 $a_m$ 出发推算第 $n$ 项,不必先回推首项。给定任意两项 $a_n$、$a_m$,公差可以反推为 $d=\frac{a_n-a_m}{n-m}$。三组公式配合,已知任意两个独立参数就能解出其余参数,对应到代码里是几个纯函数:
def ap_term(a1, d, n): # 等差数列第 n 项:a1 + (n-1)*d return a1 + (n - 1) * d def ap_term_from_am(am, d, m, n): # 从已知第 m 项出发求第 n 项:a_m + (n-m)*d return am + (n - m) * d def ap_common_diff(an, am, n, m): # 由任意两项反推公差,调用时需保证 n != m return (an - am) / (n - m)ap_term的参数是首项a1、公差d、下标n,返回第 $n$ 项,时间复杂度 O(1)。ap_term_from_am在题目只给出中间某项和公差时更省事,省去先求首项的中间步骤。ap_common_diff返回浮点数,如果题目保证所有项是整数,可以先用(an - am) % (n - m) == 0判断能否整除,再做整数除法,避免精度丢失。实际写算法题时,我会把这类纯计算函数放在一个sequences模块里,配几组 doctest,后续所有等差数列相关分支都复用同一套实现。
2.2 前n项和公式的几何意义:Sn是二次函数,公差藏在系数里
前 n 项和有两个等价写法:$S_n=\frac{n(a_1+a_n)}{2}$ 和 $S_n=\frac{n(2a_1+(n-1)d)}{2}$。第一个适合已知首项和末项的场景,本质是倒序相加:正序写一遍,反序写一遍,每对相加都是 $a_1+a_n$,共 $n$ 对,再除以 2。第二个写法展开后是 $S_n=\frac{d}{2}n^2+(a_1-\frac{d}{2})n$,这是关于 $n$ 的二次函数。二次项系数是 $\frac{d}{2}$,常数项恒为 0。反过来,如果题目给出 $S_n=An^2+Bn$,可以直接读出公差 $d=2A$、首项 $a_1=A+B$。这个结论在做数列判断题时很常用:看到 $S_n$ 的表达式不是二次函数,或者常数项不为 0,就能判定不可能是等差数列的前 n 项和。
下面是一段随机验证脚本,比较公式求和与循环累加的结果是否一致:
import random def ap_sum_formula(a1, d, n): # 公式求和:n * (2*a1 + (n-1)*d) / 2 return n * (2 * a1 + (n - 1) * d) // 2 def ap_sum_loop(a1, d, n): total = 0 for i in range(n): total += a1 + i * d return total for _ in range(1000): a1 = random.randint(-100, 100) d = random.randint(-10, 10) n = random.randint(1, 100) assert ap_sum_formula(a1, d, n) == ap_sum_loop(a1, d, n)代码里用整除// 2而不是浮点除法,是因为 $n \cdot (2a_1+(n-1)d)$ 一定是偶数,这是等差数列求和的整数性质,浮点除法反而可能引入 1e-15 级别的误差。随机参数的取值范围覆盖了负首项、负公差,循环 1000 次全部通过,说明公式在整数场景下是封闭且可替代循环的。另一个验证角度是对 $S_n$ 做差分:$S_n-S_{n-1}=a_n$,这也是沟通递推定义与二次函数模型的桥梁。
| 已知条件 | 常用公式 | 复杂度 | 边界注意 |
|---|---|---|---|
| 首项、末项、项数 | $S_n = \frac{n(a_1+a_n)}{2}$ | O(1) | 项数为正整数 |
| 首项、公差、项数 | $S_n = \frac{n(2a_1+(n-1)d)}{2}$ | O(1) | $n=0$ 时结果为 0 |
| $S_n = An^2+Bn$ | $d=2A$,$a_1=A+B$ | O(1) | 常数项必须为 0 |
2.3 用Python验证等差数列的性质:下标和相等则项和相等
讲义里性质①是:若 $p+q=m+n$,则 $a_p+a_q=a_m+a_n$。这个性质成立的根源是通项为下标的一次函数。但要注意它是必要条件,不是充分条件。比如 $1,2,4,5,7$ 这个序列也能满足"下标和相等则项和相等",但它不是等差数列。真正可靠的判定方法是差分数列全部相等。下面代码同时实现差分数列判定和性质抽查:
def is_arithmetic(seq): # 通过差分数列判断是否等差数列 if len(seq) <= 2: return True d = seq[1] - seq[0] return all(seq[i] - seq[i - 1] == d for i in range(2, len(seq))) def property_spot_check(seq): # 随机抽下标验证 p+q == m+n 时项和相等 n = len(seq) for _ in range(1000): p, q, m = random.sample(range(n), 3) s = p + q - m if 0 <= s < n and seq[p] + seq[q] != seq[m] + seq[s]: return False return Trueis_arithmetic一次遍历比较相邻差分,时间 O(n),比套用 $S_n$ 二次函数直接。property_spot_check里random.sample取出的三个下标可能使s越界,所以必须加上0 <= s < n的前置判断。性质抽查适合作为单元测试的补充,但不能作为主判据。判断一个序列是否为等差数列,永远以差分全相等为准。
3. 等比数列:错位相减推导、前n项和的边界条件与数值实现
3.1 从递推定义到通项公式:公比q的边界值
等比数列的定义式是 $\frac{a_{n+1}}{a_n}=q$,$q$ 为公比。写成乘法递推 $a_{n+1}=a_n q$ 后,通项收敛为 $a_n=a_1 q^{n-1}$。这个定义隐含一个约束:所有项都不能为 0,否则后一项无法通过除法定义公比。因此 $0,0,0,\dots$ 虽然满足乘法递推,但不满足等比数列的比值定义,做题时通常直接排除。通项变式 $a_n=a_m q^{n-m}$ 与等差数列变式逻辑相同,区别是把加法换成乘法。已知两项反推公比时 $q=\sqrt[n-m]{a_n/a_m}$,要求 $a_n/a_m>0$,否则实数范围内无解或出现多解,代码里容易被忽略。
def gp_term(a1, q, n): # 等比数列通项:a1 * q^(n-1) if n == 1: return a1 return a1 * (q ** (n - 1)) def gp_common_ratio(an, am, n, m): # 反推公比:q = (an/am)^(1/(n-m)) if n == m: raise ValueError("n 不能等于 m") if am == 0: raise ValueError("分母不能为 0") return (an / am) ** (1 / (n - m))gp_term对负公比场景也能正确处理:Python 的q ** (n-1)在指数为偶数时返回正数、奇数时返回负数,与数学定义一致。gp_common_ratio返回浮点数,当an / am为负数时会得到复数结果,工程上需要先判断符号再决定是否取绝对值后补符号。如果题目保证公比为整数,更好的做法是先取近似整数回代验证a_m * q**(n-m) == a_n,避免浮点误差导致误判。等比比等差多出的这层边界,本质上来自乘法和除法的符号敏感性。
3.2 错位相减推导前n项和:q=1的单独分支
等比数列前 n 项和公式的推导是错位相减的标准示范。设 $S_n=a_1+a_1q+\dots+a_1q^{n-1}$,两边同时乘以 $q$ 得到 $qS_n=a_1q+a_1q^2+\dots+a_1q^n$。用前者减后者,中间 $n-1$ 项全部抵消,剩下 $(1-q)S_n=a_1(1-q^n)$。这一步必须停下来判断 $1-q$ 是否为 0:当 $q=1$ 时,等式左边为 0,无法通过除法求解;这时候数列退化为常数列,前 n 项和是 $n a_1$。当 $q\neq1$ 时,才有 $S_n=\frac{a_1(1-q^n)}{1-q}$。讲义里另一个写法 $\frac{a_1(q^n-1)}{q-1}$ 分子分母同时变号,适合 $q>1$ 时使用,避免分子分母同时为负的不适感。
def gp_sum_naive(a1, q, n): # 等比数列前 n 项和,q == 1 分支不可省略 if q == 1: return a1 * n return a1 * (1 - q ** n) / (1 - q)这段代码最关键的参数是q,它决定走哪个分支。q == 1时若沿用除法公式,(1 - q)为 0,运行时报 ZeroDivisionError。即使不报错,在q无限接近 1 时分子分母同时趋向 0,结果也会不稳定。所以等比数列求和代码里,q == 1的判断必须放在最前面。错位相减的推导过程本身也是第 4 章"等差×等比"求和的原始模板,建议把这一步手推一遍,比直接背公式更能记住适用条件。
3.3 等比求和代码的浮点稳定性与取值边界
gp_sum_naive数学上正确,工程上还有两个坑。第一个是浮点误差:$q$ 接近 1 时,1 - q**n和1 - q都是小量,相除会放大相对误差;$n$ 很大且 $|q|>1$ 时,q**n可能溢出为inf。第二个是符号处理:1 - q**n在 $q>1$ 时为负,1-q也为负,分子分母同号结果为正,但中间过程的绝对值很大,可能丢失精度。常见做法是根据 $|q|$ 选择等价形式:
def gp_sum_stable(a1, q, n): # 稳定的等比求和:根据 |q| 选择公式形式 if q == 1: return a1 * n if n <= 0: return 0.0 if abs(q) > 1: return a1 * (q ** n - 1) / (q - 1) return a1 * (1 - q ** n) / (1 - q)当 $|q|>1$ 时改用(q**n - 1) / (q - 1),分子分母都朝正方向增长,避免两个小数相减;当 $0<q<1$ 时保留原形式。n <= 0分支处理空和场景。另外,当 $|q|<1$ 且 $n\to\infty$ 时 $q^n\to0$,前 n 项和收敛到 $\frac{a_1}{1-q}$,这个极限在几何分布期望、缓存命中率预估中很常见,可以用gp_sum_stable(a1, q, 100000)与极限值对比,误差应小于 1e-6。
| q 的取值范围 | Sn 的形态 | 代码注意点 |
|---|---|---|
| $q=1$ | $n a_1$ | 独立分支,否则除零错误 |
| $q>1$ | $\frac{a_1(q^n-1)}{q-1}$ | 用(q**n - 1)/(q - 1)避免符号混乱 |
| $0<q<1$ | $\frac{a_1(1-q^n)}{1-q}$ | n 较大时趋近于 $\frac{a_1}{1-q}$ |
| $-1<q<0$ | 正负交替但有界 | 浮点累计误差随 n 增大 |
| $q<-1$ | 正负震荡且幅度增大 | 幂运算符号按奇偶变化,结果不稳定 |
4. 等差与等比的类比:三种求和技术选型与典型拆分
4.1 类比关系表:和差与积商的对应,以及对数变换
等差数列做加法,等比数列做乘法。把两者并排看,很多公式可以成对记忆:和对应积,差对应商,系数运算对应指数运算。讲义里的类比表还隐含一个隐藏技巧:正项等比数列取对数后变成等差数列,因为 $\log(a_n)=\log(a_1)+(n-1)\log q$,形式与等差数列通项完全一致。这个变换在算法分析中很有用,比如快速幂递归层数 $T(n)=T(n/2)+O(1)$ 展开后的调用次数就是一个等比数列,取对数后层数就是 $\log_2 n+1$。
| 维度 | 等差数列 | 等比数列 |
|---|---|---|
| 递推关系 | $a_{n+1}-a_n=d$ | $a_{n+1}=q a_n$ |
| 通项形态 | 一次函数 $dn+b$ | 指数函数 $a_1 q^{n-1}$ |
| 中项条件 | $2b=a+c$ | $b^2=ac$ |
| 前 n 项和 | 二次函数 | 指数式(分段) |
| 特殊退化 | $d=0$ 为常数列 | $q=1$ 为常数列 |
| 常用变换 | 差分 | 取对数 |
这组类比还有一个容易忽略的方向:等比数列的判定不能只靠比值恒定,还要排除首项为 0 的特殊场景;等差数列判定没有类似的排除项,任何常数公差都能定义。所以写代码做类型判断时,等差和等比的判定逻辑不能直接复制同一套模板。理解了这层差异,后面三种求和套路的分工就清楚了。
4.2 分组求和:把通项拆成等差部分与等比部分
如果一个数列的通项是等差部分与等比部分的简单叠加,比如 $a_k=k+2^k$,那么前 n 项和可以直接拆成 $\sum_{k=1}^n k+\sum_{k=1}^n 2^k$。前一部分用 $\frac{n(n+1)}{2}$,后一部分用 $2^{n+1}-2$。这种拆分依赖求和运算的线性性质:和的求和等于求和的和。代码实现时,整数运算优先于浮点运算:
def group_sum(n): # S = sum_{k=1}^n (k + 2^k) sum_part_ap = n * (n + 1) // 2 sum_part_gp = 2 ** (n + 1) - 2 # a1=2, q=2 return sum_part_ap + sum_part_gp for n in [1, 5, 10, 100]: brute = sum(k + 2 ** k for k in range(1, n + 1)) assert group_sum(n) == brutesum_part_gp之所以是2 ** (n + 1) - 2,来自等比求和公式 $\sum_{k=1}^n 2^k=2^{n+1}-2$,首项 2、公比 2。如果公比不是整数,再改用上一章的gp_sum_stable。分组求和的关键前提是通项能拆成两个标准数列的和,且两部分下标范围一致。遇到 $a_k=k\cdot2^k$ 这种乘积形式,分组求和不再适用,需要切换到错位相减。
4.3 裂项求和:构造相邻项差,让中间项全部抵消
裂项求和的核心是:把一个通项改写成相邻两项的差,求和时中间项成对抵消,只剩下首尾。最经典的恒等式是 $\frac{1}{k(k+1)}=\frac{1}{k}-\frac{1}{k+1}$,于是 $\sum_{k=1}^n\frac{1}{k(k+1)}=1-\frac{1}{n+1}$。讲义还给了分母为两个奇数因式的变式:$\frac{1}{(2k-1)(2k+1)}=\frac{1}{2}\left(\frac{1}{2k-1}-\frac{1}{2k+1}\right)$。判断是否该用裂项的快速标准:通项是分式,分母是两个因式相乘,且两因式之差为常数。
def telescoping_sum_1(n): # sum 1/(k*(k+1)), k=1..n return 1.0 - 1.0 / (n + 1) def telescoping_sum_2(n): # sum 1/((2k-1)*(2k+1)), k=1..n return 0.5 * (1.0 - 1.0 / (2 * n + 1))第二种写法里裂项后首项是 $\frac{1}{1}$,末项是 $\frac{1}{2n+1}$,系数 $\frac{1}{2}$ 很容易丢。写代码验证时通常保留一个暴力累加函数,把 n 从 1 到 1000 全部比较一遍。裂项求和的思想在工程里也有对应:如果一段数据能表示成相邻状态的差,累积过程就只需要维护当前状态,不需要保留全部中间结果,这跟滑动窗口维护增量是一个道理。
4.4 错位相减:处理等差×等比的通项
当通项因子是等差数列乘以等比数列,例如 $a_k=k q^{k-1}$,分组与裂项都不适用。此时用错位相减:设 $S=\sum_{k=1}^n k q^{k-1}$,两边乘以 $q$ 后与原式相减,二次整理得到闭合公式 $S=\frac{1-(n+1)q^n+nq^{n+1}}{(1-q)^2}$,限制条件 $q\neq1$。这个公式在二叉树路径计数、几何分布期望中经常出现。代码里同时保留公式版和暴力版,小规模输入下互相校验:
def sum_k_qk_formula(n, q): # S = sum_{k=1}^n k * q^(k-1), q != 1 if q == 1: return n * (n + 1) // 2 numerator = 1 - (n + 1) * (q ** n) + n * (q ** (n + 1)) return numerator / ((1 - q) ** 2) def sum_k_qk_brute(n, q): return sum(k * (q ** (k - 1)) for k in range(1, n + 1)) for n in range(1, 20): for q in [0.5, 2, -1]: assert abs(sum_k_qk_formula(n, q) - sum_k_qk_brute(n, q)) < 1e-9numerator的三项分别来自错位相减后的首项、交叉尾项和末项修正;$q^n$ 与 $q^{n+1}$ 由公式统一管理,负公比时也能通过测试。这个公式对 $q=1$ 不适用,代码里单独返回等差数列求和结果。工程实现时如果 n 很大且 q 接近 1,应优先考虑分数形式或高精度库,避免浮点误差被二次方项放大。
5. 公式落地:递推回代、符号计算与取模验算
5.1 递推生成前N项回代封闭式
拿到公式后第一步不是直接用,而是先用递推生成前 N 项回代。递推是定义层的唯一标准,封闭公式是推导层的结论,两者一致才说明公式没有用错。下面的函数把等差通项、等比通项分别与递推生成结果做近似比较:
def validate_seq(a1, d, q, n): ap_expected = [a1 + i * d for i in range(n)] gp_expected = [a1 * (q ** i) for i in range(n)] ap_loop, gp_loop = [a1], [a1] for i in range(1, n): ap_loop.append(ap_loop[-1] + d) gp_loop.append(gp_loop[-1] * q) ap_ok = all(abs(x - y) < 1e-9 for x, y in zip(ap_expected, ap_loop)) gp_ok = all(abs(x - y) < 1e-9 for x, y in zip(gp_expected, gp_loop)) return ap_ok, gp_ok等比部分在q为负数且 n 较大时,浮点乘积的符号会反复变化,abs(x-y)<1e-9的容差仍然够用。这个验证函数的参数a1、d、q、n分别对应首项、公差、公比和生成长度,放在单元测试里可以快速拦截公式抄错、参数顺序写反这类低级问题。
5.2 用SymPy做符号推导校验
对需要推导的场景,可以用 SymPy 做符号级求和,避免手推错位相减时漏项。下面的代码声明符号变量后直接计算两个典型求和并化简:
from sympy import symbols, summation, factor k, n = symbols('k n') s1 = summation(k, (k, 1, n)) s2 = summation(k * 2 ** (k - 1), (k, 1, n)) print(factor(s1)) # n*(n+1)/2 print(factor(s2)) # 2**n*(n-1)+1s1输出n*(n+1)/2,与等差数列求和公式一致;s2化简后是 $2^n(n-1)+1$,可以快速验证第 4 章的错位相减公式。符号计算适合检查通项拆分是否正确,但不能替代浮点验证,因为符号计算不涉及溢出和精度问题。
5.3 取模场景下的等比求和:逆元与pow组合
算法题里经常要求结果对一个大质数取模,等比求和公式不能直接用浮点除法,需要把分母 $1-q$ 换成逆元。Python 3.8 之后的内置pow支持负指数求模逆元,实现如下:
def gp_sum_mod(a1, q, n, mod): # 等比数列前 n 项和取模, q != 1 if q == 1: return (a1 % mod) * n % mod num = (pow(q, n, mod) - 1) % mod den_inv = pow(q - 1, -1, mod) # Python 3.8+ 支持模逆元 return (a1 % mod) * num % mod * den_inv % modpow(q, n, mod)是快速幂取模,时间复杂度 O(log n);pow(q - 1, -1, mod)返回q-1在模mod下的逆元。使用前提是mod为素数且q-1与mod互质。若q == 1走独立分支,返回a1 * n % mod,此时不存在分母,不需要逆元。调用时注意a1也要取模后再参与乘法,避免 Python 大整数在mod较小时拖慢速度。
本文还有配套的精品资源,点击获取