线段树初步理解
今天ZRtes爆零咯,就不在tes里写了
引言:以前一直只会用线段树2,线段树也是一直当做工具使用,一切线段树的科技除了线段树分治基本都不会,因此特作此文记之
线段树的 lazytag
与 pushdown
为了保证时间复杂度,线段树在做区间修改的时候引入了
lazytag
的概念,目的是为了节省没必要的时间复杂度,但是由于有了这个懒标记的存在,导致线段树的节点之间的时间维度是不统一的(父亲比儿子更加接近现在的状态),因此可以把lazytag
看做是一个操作的缓存,而pushdown
则是用父亲节点更加先进的状态来更新儿子节点落后的状态,也就是把父亲节点的缓存清空,缓存的内容一方面用于更改儿子的落后状态,一方面接入到儿子的缓存中,以备更新儿子的儿子。
线段树节点 标准状态
的定义
观察线段树的代码,发现当
L<=l&&r<=R
的时候更新完当前节点后就会退出函数,不在递归,这其实是对标准状态的修改,就比如线段树1
中的add
的tag
本质上就是对于线段树节点标准状态的一个修改(或者叫做增量)。而一个线段树的标准状态
是在其把缓存都推给儿子之后,递归完儿子之后用儿子的信息来更新父亲节点,这个时候就会对标准状态重新求值,然后所有的增量全部清零,就是有点像把所有的缓存的给永远刻在这个节点上
线段树维护历史版本和
这个时候还需要记一个标记:在这个节点上,相对于时间轴来说有多少次操作是没有被传给儿子的,因此在统计到这个点的时候,一方面所有祖先的这个标记都传给为了当前节点,因此当前节点就是现在状态,而在把这些标记全部传给儿子,想办法把这些操作时儿子的历史和的贡献算出来,把儿子递归完之后,把儿子的状态传回来,更新标准状态,刻进这个节点里头。