递推 | 差分前缀和
<目录
这两个算法都是将后面的情况和前面的情况结合,所以放在一起讲了。
递推 \(\sf\small\color{gray}Recursion\)
基本思想
观察生活,很多事情随着规模或阶段的上升而变得越来越复杂。
然而,此规模或阶段往往又和前面的规模或阶段有着联系。
找出这个联系并解决问题的算法就叫递推。
模型
\(\sf\small\color{CCCCCC}以下均为个人总结,请不要将其视为官方说法!\)
F-G-F 模型
如名,就是在 F 数组与 G 数组之间进行的递推。
斐波那契 Fibonacci 数列 \(\sf\small\color{CCCCCC}兔子数\)
定义
兔子出生后一个月就可以长成大兔,一对大兔每个月都能生育一对小兔。一开始只有一对小兔,第 N 月有几对兔子?
递推式
设第 i 月有 F(i) 对小兔, G(i) 对大兔。
F-F 模型
如名,就是在 F 数组内部之间进行的递推。
斐波那契 Fibonacci 数列 \(\sf\small\color{CCCCCC}台阶数\)
定义
有 N 节楼梯,每次可以走一步和两步。走到顶有几种走法?
递推式
差分与前缀和
A={ +1 +2 +5 +3 +6 +3 +7 }
差分 \(\sf\small\color{gray}Differences\)
差分是解决区间操作使用的。
优势在于本来需要遍历的区间四则运算转化成了端点操作。
区间加减
转为差数组
记录这一个数和上一个的差。
兼容区间加减。
/B[0]=A[0]
\B[i]=A[i]-A[i-1]
B={ +1 +1 +3 -2 +3 -3 +4 }
还原
根据差数组的定义反向操作还原数组。
/A[0]=B[0]
\A[i]=A[i-1]+B[i]
区间加
区间 \(\sf(m,n)\) 加 \(\sf k\) 。
对端点操作,复杂度为 \(\sf O(1)\) 。
B[m]+=k;
B[n+1]-=k;
区间减
区间减 \(\sf k\) 可视为区间加 \(\sf -k\) 。
区间乘除
转为分数组
/C[0]=A[0]
\C[i]=A[i]/A[i-1]
C={ +1 +2 +2.5 +0.6 +2 +0.5 +2.33 }
还原
操作类似差数组。
/A[0]=C[0]
\A[i]=0.1+A[i-1]*C[i]
\(\sf\small\color{FF0000}注意精度!\)
区间乘
区间 \(\sf(m,n)\) 乘 \(\sf k\) 。
对端点操作。差分复杂度始终为 \(\sf O(1)\) 。
C[m]*=k;
C[n+1]/=k;
区间除
C[m]/=k;
C[n+1]*=k;
前缀和 \(\sf\small\color{gray}Perfix\ Sums\)
前缀和主要作为统计区间和的工具。
真·前缀和
D[i] 存储前 i 个的和。
转前缀和数组
/D[0]=A[0]
\D[i]=D[i-1]+A[i]
区间求和
区间 \(\sf(m,n)\) 的和为 D[m]-D[n-1] 。
前缀积
类比前缀和,我们可以总结出前缀积的做法,可求区间积。
转前缀积数组
/E[0]=A[0]
\E[i]=E[i-1]*A[i]
区间求积
区间 \(\sf(m,n)\) 的积为 D[m]/D[n-1] 。
\(\sf\small\color{FF0000}注意范围!\)
完结散花
突然发现还有二维差分、二维前缀和积
不写了,逃
PCwqyy

浙公网安备 33010602011771号