新的一周结束,说一说这周学了什么,这周看了有五十来篇左右的博客或是题,有一些算法基础,和一些数据结构,总的来说是一些不容易想到的优化方法,比如前缀和的方法,我们之前高中学的数列前几项的和就跟这个很像,比方说设sn为数组xn的前n项和,那么sn的表达方式有两种,一种是,另一种是
,如果我们用第一种明显效率要慢,所以通常使用第二种,这种方法其实挺实用的,在一些小地方上可以优化效率,从这个地方其实就启示我们,对于一个数组,其中不止可以储存数值,还可以储存状态值,或者说是过程值,用来表示一个区域内的值,而不是某单个数值。除了一维数组,二维数组也是这个道理不过区别就是一维数组是单向的,他前面只有一个方向存储,而二维的数组是有不止一个方向有两个方向来存储区域值要更复杂点,但总体大同小异,都是向我们传递一个信息,就是将存储信息值的地方替换成状态值,会更加有效率。接着是与其类似的比方说快速幂,当我们求
时我们可以将
写成
,也就是
这样来算,由此就引申出一个算法叫倍增,顾名思义就是倍数增长,经典例题就是小白兔跳格子,
根据上面的总结我们得出,想要提高效率那么数组中就要存储的是状态值,而非冗杂的单个数据值,因此我们知道当存储的数据越少,效率会更高,我们储存状态值实际上就是大大减少了存储的信息量,于是我们可以获得2这个神奇的数字,就如上面说的小兔子跳格子,小兔子从1跳到任意数字比如说7,他可以选择一步步跳,当然这意味着花费的时间更多,我们上面说到2是个神奇的数字,我们可以首先考虑2个2个的跳,也就是2的等差数列,对于2的整数倍我们可以正好跳到,而不是2的整数倍,比如7我们只需到规定的数字前一个数6再+1就可以了,那有没有更高效的方法呢,有,就是等比数列,2的次方效率会更高,,也就是1 2 4 8 16...的方式跳,我们只需要跳到规定数之前,然后再从1 2 4 8 16...里选一个合适的数跳,总能跳到,因为2是个神奇的数字,这样她就可以到达任意一个数字上面了,基于倍增算法,又有st表等
但是这些都只做查询用而不能进行修改,因为就像前面说的数组储存的是状态值,这个位置修改了,那么其他状态值就会都改变,修改起来很麻烦,于是又有了树状数组,其有两个特别之处,第一是使用了二进制进行区间的划分,而二进制的区间划分是用的后缀和,比如6的二进制是110它可以分成100+10,那么它是利用后缀和进行划分的(取最低位的1)于是我们还发现后缀和都是由一个2的幂组成,如4的二进制是100取最低位1还是100,因此依据2的幂呈倍数增长,我们修改起来也会很容易,因为我们不用一个个修改了,只要修改相应的2次幂就可以了。
总结:这些方法都是一个核心思想就是通过倍增进行效率优化的,通过前缀和,逐步引入倍增,通过用数组储存2次幂的信息比储存一个单位的信息效率要高得多,这些思想也极大地启发了我,不能禁锢思想,思维要活跃,