分治,剃刀,奥卡姆
分治在于剔除重复。
“如无必要,勿增实体” (Entities should not be multiplied unnecessarily)
树上的log是轻重儿子,启发式合并。
而序列上则是分治。
线段树本身就是一种分治。
序列上的分治是二分。树结构其实可以看成特殊的序列。
而分治本身在于继承。
继承是为了不必重复计算。类比记忆化搜索。
序列上,如CDQ分治,如奇袭,本质上都是多对多地共用已经处理出来的信息。而不是每一次去单独算。
仔细想想树状数组之所以能快也是种信息共享的结构。
树状数组:单点修改,区间查询。改为差分数组可做到区间修改,单点查询。
同时序列上的二分,mid能覆盖所有中间分割位置。
实际上原本是n^2的点对,每对点都有关系。通过二分(实际上是枚举断点(分为 贡献—接受 部分))使接受的部分能够共享贡献的部分的贡献。
实现的关键在于1、每个点都对整个序列有影响。(n^2点对)。则可以分出接受和贡献的部分。
2、每个点的贡献可以单独计算。不能单独算可以考虑公式移项。(奇袭,天天爱跑步)。
在增加数值,查询数值时,可以考虑数据结构维护(CDQ的树状数组)。或者只用一个数组或桶。
对于区间,我们可以分为内部和外部来讨论,从而写出分治。那么对于树,我们也可以分为子树内部,子树对根,(可能还有子树对子树)来考虑。
如果要先处理所有子树信息,再处理根节点,且子树的信息要累加到根上,且信息处理有继承关系:
1、每个节点开空间记录所有信息。
2、为了降低复杂度,可以继承信息多的部分,从而做到每次只额外增加较少的信息,处理较少的信息。
根据轻重子树分(轻重根据信息分,而非子树大小),可以每次增加不超过1/2.
从而实现log的复杂度。
二:同类信息的简化
背包DP中有数量物品的二进制拆分。
三:运动与转移
造成重复的除了信息,还有运动/变化/转移。为了简化若干相同的连续的转移,出现了快速幂、矩阵快速幂。
而它们的必要条件是转移满足结合律。
顺便一提,快速幂是把底数的乘法变为指数的加法,并且自乘相当于指数乘2,二进制中即为左移一位。
如果一个个乘,相当于把base又算了一遍。乘法本身就是对加法的优化,用两个较小的数表示一个较大的数。扩展到快速幂就是让指数乘2。
类似的还有lca抬根(ST表)。也是对一系列不断重复操作(向上抬)的简化。ST表既可lca抬根优化转移,也可RMQ存储区间信息。
大体来说,对于转移的简化重复,一是快速幂从低位到高位枚举二进制,二是lca抬根的二进制从高位到低位拼凑。
LAST:
寻找冗余。
信息是物质,转移是运动。剔除重复。避免不必要的事、物。