为何叫入门随讲呢……由于我也刚学完啊html
点分治(这不是要学动态点分治吗)算法
线段树(会点分治不会线段树?)数据结构
其实线段树是来帮助理解的。spa
句句经典……在点分上没有必定造诣还真写不出来。htm
墙裂推荐一观,文笔和思想都比某hr好多了。blog
点分治是一种人人喜欢的算法。它含钙高,吸取好思想比较简单,代码实现也不难,复杂度瓶颈在统计跨重心root的链对答案的影响/贡献。get
可是点分治的缺点是很明显的:它只能作离线问题!换句话说,它不支持修改操做。qt
这个时候就须要动态点分治来帮帮忙了。 io
这个时候咱们已经对点分治的理解很深了。它经过巧妙地在k级重心处划分,把树上的路径划分红了两类:通过重心的和不通过重心的。
之因此复杂度有保证,是由于每一个点做为链端点只会被统计log次。
带修改的话,暴力确定是询问一次作一次点分。
注意到修改的基本是点权之类的而不是树的形态。换言之,每次的点分过程是同样的!
而后又想到每一个点只会被统计log次——胡不重构此树乎?
讲清楚点:既然每次修改只会改一个点,只会把它做为端点的链的信息改掉。
(要是你改一个点会引发多个点改动也不像是树分治题而更像传统数据结构题)
其余的点的信息该是多少仍是多少,是不变的过往,是永恒的黑暗与孤独——打住。
屡次处理重复相同信息,是必不可能被咱们所称赞的。而这些信息总的数量级又只有O(nlogn)级别。
为何不把它事先保存,而后对于每次修改,O(logn)级别地暴力一一修改呢?
每次查询,要么直接取,要么暴力跳一个点的重心祖先链,复杂度也很优秀。
即:预处理点分治一遍,把分级重心树搞出来,把信息存进去。
每次操做,修改即想办法修改本身到祖先重心链上的信息便可。
询问呢,你都维护了这么多东西了,也是想办法快速求就能够了。
好比说取最大值,那就开堆嘛(ZJOI捉迷藏)。
再好比说HNOI开店,用vector动态申请空间,排序一下,每次询问暴跳祖先。
提及来好像很简单,实现起来倒是如人饮水冷暖自知。
剩下的我一时也不知道还能讲什么了?……
送一句话:树上的动态点分治就至关于序列上的线段树。
忘记是从哪一个神犇那蒯的了……
两点lca什么的别用倍增了,用欧拉序列+ST表预处理O(1)搞定。
还有记得把log也预处理出来,系统超慢。
开堆开桶之类的,vector或new