今天刚看了看zkw线段树,也找了几个代码先交上去试了试,发现确实比普通的线段树快好多。。。然后就开始认真看ppt(ppt请百度统计的力量)了。。。
我认为他的线段树之所以能接近树状数组的速度,就是因为他的线段树的修改数据的过程相当接近树状数组。
树状数组是从某个位置开始,修改几个点,点的个数和log n有关系。
而普通的线段树在做区间修改的时候,由于是标记下放,所以导致修改的点数是越来越多,点的个数和2^k(这个k又和log n有关系)有关系。这样一比,速度差距当然就出来了。
而zkw的树在更新时,采取标记上浮的方法,而且是只要上浮所要修改区间的左右两端点的标记即可。这样的话,其修改过程是两条路,每条路上点的个数和log n有关。这样,他的修改过程顶多是树状数组的2倍,其耗时当然也就不会和树状数组相差太多了。
所以zkw的树的精髓不是那个用堆储存线段树的地方(我看网上好多所谓zkw树就是把普通的线段树用堆式结构存了一下,其余地方和普通线段树无异),而是采用上浮标记的方法来更新树内的信息(之所以是查询开区间,也是为了保证上浮标记的过程可以顺利执行,并不是绝对要开区间的)。在更新树的时候,貌似经常使用差分的方法来将普通的标记下沉转换为他的树中的标记上浮。
而这个上浮的过程中之所以只要上浮两个端点的标记,那就是他在ppt中所说的所谓标记永久化的思想,标记即为储存的内容。从而不需要为了修改标记而去反复修改树上存的值,因为树存的东西本身就是标记。
个人感觉,zkw的树在使用范围上应该无法达到普通线段树所能涉及的范围(只用堆存线段树的方法绝对不能称为zkw线段树)。但是,只要能用到他的树的地方,绝对可以远快于普通线段树。而且,他的使用范围也大于树状数组,这样在有些问题上zkw树就成了是最佳的选择。
暂时从ppt里触及到的就只有标记上浮还有差分这两个实用的将一般线段树转换成zkw线段树的技巧。他的ppt肯定没有将树的精髓表现出来。。。只能慢慢揣摩出来一点了。。。
他的ppt中对区间更新,外加动态查询rmq的地方有几处错误,比如区间标记未上浮到顶,rmq查询应该是闭区间不是开区间,等等。
这里是我对区间更新,动态查询rmq的讲解,大家可以去看下。。。