胡乱分析
说到线段树实际上还是一个具有叫做lazy tag的完全二叉树
分布操作
建树
建树操作需要知道一个就是当前p的左儿子是2p右儿子是2p+1然后我们递归建树即可,回溯的时候更新每个值
所以代码就比较清晰了,如果当前l=r的话那么我们就把这个叶子节点赋值然后向上回溯即可
1 | void build(int p,int l,int r) |
lazy tag下放
lazy tag在这里是记录区间总共更改了多少,下放的时候要注意更改左右儿子的值并且把左右儿子的lazy tag更新,自己的lazy tag清除
1 | void lazy(int p) |
更改操作
更改是把父节点对应的子节点的个数乘以修改的值,因为每个节点都加上一个数,所以一次把加和给父节点,并且给父节点打上lazy tag,如果修改的区间并不覆盖父节点所管理的范围,那么下放lazy tag并且递归更改其他区间,最后回溯赋值
1 | void change(int p,int x,int y,int z) |
查询
查询需要看当前是不是已经区间覆盖了,如果是那么返回当前的区间的值,否则还是下放lazy tag进行递归寻找
1 | long long sum(int p,int x,int y) |
完整模板(洛谷P3372 【模板】线段树 1)
1 |
|