线段树区间更新 延时标记
来源:互联网 发布:面板数据加入虚拟变量 编辑:程序博客网 时间:2024/06/05 20:01
我在这块里先给一个B站学习线段树视频的链接,如果下面的例子看不懂的话可以去看看这个线段树的视频
http://www.bilibili.com/video/av9801549/
struct Tree{int left,right;long long lazy,sum;void update(long long x){//更新值函数,主要用在延时标记更新的时候sum +=(right-left+1)*x;lazy+=x;}}tree[N*4];int a[N];线段树空间开数组的4倍void push_down(int x){//将延时标记向下传int la = tree[x].lazy;if(la){tree[x<<1].update(la);tree[x<<1|1].update(la);tree[x].lazy = 0;}}void push_up(int id){tree[id].sum = tree[id<<1].sum+tree[id<<1|1].sum;}void Build(int id,int l,int r)//建树,主要用二分的思想
{tree[id].left = l;tree[id].right = r;tree[id].sum = tree[id].lazy = 0;if(l == r){tree[id].sum = a[l];}else{int mid = (l+r)/2;Build(id<<1,l,mid);Build(id<<1|1,mid+1,r);push_up(id);}}void update(int id,int l,int r,int val)//更新l-r值val;调用update(1,k,val);
{int L =tree[id].left,R = tree[id].right;if(l==L && R==r){tree[id].update(val);return ;}else{push_down(id);int mid = (tree[id].left+tree[id].right)/2;if(r<=mid)update(id<<1,l,r,val);else if(l>mid)update(id<<1|1,l,r,val);else{update(id<<1,l,mid,val);update(id<<1|1,mid+1,r,val);}push_up(id);}}long long query(int id,int l,int r)//更新a[k] = val;调用update(1,k,val);
{int L =tree[id].left,R = tree[id].right;if(l==L && R==r){return tree[id].sum;}
else
{push_down(id);int mid = (L+R)/2;if(r<=mid)return query(id*2,l,r);if(l>mid)return query(id*2+1,l,r);return query(id*2, l, mid)+query(id*2+1, mid + 1,r);
}
}
我想所有学线段树区间更新的人都会被延时标记困扰,我也是看了好久才明白延时标记是什么东西,
其实可以这么想如果我们要把[3,6]的区间的值加2我们如果恰巧遇到了[3,6]这个区间,我们就把[3,6]这个区间的延时标记更新为2然后将[3,6]这个节点的sum更新;并将延时标记传给他的左右节点同时讲左右节点的值给更新,然后可以直接退出了,不需要管[3,6]左右节点的左右节点,因为我们目前用不到这些节点,延时标记就是这样,我们暂时用不到我们就把它标记上不继续向下更新,如果后面要用的时候再进行更新延时标记下面的值,比如求和[3,4]在求和函数递到[3,4]这个点的时候发现这个点的延时标记不为0那么就把这个延时标记向下传并把左右节点的值更新,这样做可以极大的节省时间,我们没必要特意的把每个点更新而是给标记上,等要求和或者跟更新其他值的时候发现这个点还有延时标记的,我们就把这个点顺便的处理一下。
0 0
- 线段树 & 区间更新 & 延时标记
- 线段树区间更新 延时标记
- hdu1698 Just a Hook 线段树区间更新,延时标记
- 线段树区间更新延迟标记
- hdu1698 Just a Hook (线段树区间更新 懒惰标记)
- NEFU 1111 线段树区间更新+懒惰标记
- 线段树区间更新模板(lazy延迟标记)(1698)
- HDU1698 线段树+区间更新+懒惰标记-Just a Hook
- [线段树]hdu1698 Just a Hook(区间更新、延迟标记
- [线段树]poj3667 Hotel(区间合并、更新、延迟/懒惰标记
- hdu 1698 线段树区间更新入门(lazy标记)
- hdu1698 Just a Hook(线段树 区间更新+懒惰标记)
- 专题 线段树 E(区间更新,使用lazy标记)
- 线段树求区间最大值+区间更新+区间求和+lazy标记
- 线段树学习笔记(单点更新+区间查询最大值+lazy标记+pushdown操作+区间更新+求区间和)
- poj3468---线段树----区间单点更新、区间和查询----有延迟标记
- 线段树区间更新区间求和(转延迟标记精讲)
- hdu1698 Just a Hook 线段树延迟标记区间更新 求加权区间总和
- HTML img标签之onAbort、onError、onLoad事件与问题
- Hashmap为什么容量是2的幂次,什么是负载因子
- asa文件导入到mysql
- webstorm(10.0.2)的端口号修改
- postman加密请求接口
- 线段树区间更新 延时标记
- Android集成华为推送的问题总结
- That darn "libtoolize: AC_CONFIG_MACRO_DIR([m4]) conflicts with ACLOCAL_AMFLAGS=-I m4" error
- perl Email::Sender 发邮件
- 三分查找
- UNIX再学习 -- 信号
- tomcat使用log4j打印应用日志
- 网络中的各层协议
- Flume中的TaildirSource