Loading

递推 | 差分前缀和

<目录

这两个算法都是将后面的情况和前面的情况结合,所以放在一起讲了。

递推 \(\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) 对大兔。

\[\sf F(i)=F(i-1)+G(i-1) 上个月的小兔长成大兔 \]

\[\sf G(i)= \begin{cases} \sf F(i)&\sf i>1&\sf大兔生了小兔\\ \sf 1&\sf i=1&\sf一开始有一对小兔 \end{cases} \]

F-F 模型

如名,就是在 F 数组内部之间进行的递推。

斐波那契 Fibonacci 数列 \(\sf\small\color{CCCCCC}台阶数\)

定义

N 节楼梯,每次可以走一步和两步。走到顶有几种走法?

递推式

\[\sf F(i)= \begin{cases} \sf F(i-1)+F(i-2)&\sf(i>2)&\sf可以已从前一级走,也可以从前两级走\\ \sf 1&\sf(i=1or2)&\sf第一和第二级 \end{cases} \]

差分与前缀和

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}注意范围!\)


完结散花
突然发现还有二维差分、二维前缀和积
不写了,逃

posted @ 2022-09-08 17:52  PCwqyy  阅读(16)  评论(0)    收藏  举报  来源