ACM_线段树
来源:互联网 发布:广数g72内孔编程实例 编辑:程序博客网 时间:2024/06/05 14:12
线段树:
自我理解:把一段区间整体操作的数据结构
整体思路:
如图:
假如单点更新 区间查询 现在有10个数
这10个数最开始是 1 2 3 4 5 6 7 8 9 10
查询某个区间的最大值
那么把这些区间按照如下更新
现在假如我们查询 2-7的最大值 (当然主观上我们明显知道是7)
我们就可以查询max[2, 2] = 2, max[3, 3] = 3, max[4, 5] = 5, max[6, 7] = 7, 取最大的 = 7;(为什么不直接查询[2, 7]呢, 因为线段树里没有这个区间)
所以我们就知道[2, 7]的最大值是7;
现在假如我们更新其中的一个值:
比如我们把5点的值更新成100;
每个区间的最大值就成了这样
下次我们再查询max[2, 7]的时候:
max[2, 2] = 2, max[3, 3] = 3, max[4, 5] = 100, max[6, 7] = 7;
取最大的是100;
最大值就等于100;
基本结构:
每个区间都会有1个rt 代表该区间:
然后每个区间的基本结构有3个参数(l, r, rt)分别代表这个区间的左端点, 右端点, 区间的下标)
首先 整个区间的下标用1表示
每个区间的中点m = l + r >> 1;
然后每个父节点有一个左儿子:(l, m, rt << 1)一个右儿子(m+1, r, rt << 1 | 1)如此建树
几个函数:
void push_up(向上推)
void push_donw(向下推, 当然这个题不需要这个功能, 求区间和的时候需要)
void build(建树)
void update(更新某些值)
int query(查询符合要求的值)
void push_up
void push_up(int rt){ h[rt] = max(h[rt << 1], h[rt << 1 | 1]);}
h代表最大值 [l, r]的最大值等于它左儿子的最大值和右儿子的最大值里大的那个;
build
void build(int l, int r, int rt){ if(l == r){ scanf("%d", &h[rt]); return; } int m = l + r >> 1; build(lson); build(rson); push_up(rt); }
当不断向下搜索知道l = r的时候, 那么这个区间就只有1个值, 那么这个值一定就是最大值, 读入它;
否则 我们把它的左边儿子建立了, 右边儿子建立了, 再从它左儿子和右儿子两个最大值中取大的那个;
建树后就变成了上图, 其中黑色底字是区间, 红色的字是区间的最大值, 绿色的字是区间的下标
void update
void update(int x, int y, int l, int r, int rt){ if(l == r){ h[rt] = max(h[rt], y); return; } int m = l + r >> 1; if(x <= m) update(x, y, lson); else update(x, y, rson); push_up(rt);}
如果l = r 说明该区间只有1个值了, 那么更新到这里把需要更新的值读入就OK了, 该值一定是最大值
否则就继续向下更新 并在两个儿子的最大值中取最大的那个比如更新把5更新成100
按照天蓝色的线更新:注意一下路上区间的最大值变化(红色的字)
- int query
int query(int L, int R, int l, int r, int rt){ if(L <= l && r <= R) return h[rt]; int ret = -INF; int m = l + r >> 1; if(L <= m) ret = max(ret, query(L, R, lson)); if(R > m) ret = max(ret, query(L, R, rson)); return ret;}
查询函数: if(L <= l && r <= R)说明查询的区间已经包含到了向下询问的空间了, 直接返回这个区间的最大值就OK了
否则就返回它的左儿子和右儿子的最大值中较大的那个就OK了;
顺着天蓝色的线向下找, 找到这些区间的最大值并返回就OK
- ACM_线段树
- ACM_模板_线段树
- ACM_线段树模板(单点更新)
- ACM_线段树模板(区间更新)
- ACM_大牛总结的线段树专辑
- ACM_字典树模板
- ACM_图论_表达式树
- ACM_模板_字典树
- ACM_模板_最小生成树
- acm_起点
- acm_蜂巢
- acm_求最值
- ACM_ Classy
- ACM_阶段性总结 ACM_动态规划(DP)
- 线段树?线段树!
- 线段树?线段树!
- 线段_线段树
- 线段_线段树
- MD5校验
- 像素填充率,纹理填充率,显存带宽
- Linux下Gcc生成和使用静态库和动态库详解
- Unity文件转移出现的粉红色材质的处理方法
- 关于OpenCV3版本与MFC配合显示图片
- ACM_线段树
- 关于 gradle 编译报错的问题
- java项目部署到tomcat启动时报错java.lang.IllegalAccessError: cl org.xml.sax.helpers.SecuritySupport12 cannotass
- [sicily]1753. 解码
- zabbix监控tomcat
- Ubuntu上编译hostapd
- 获取Jar包版本的简单方法
- 面试遇到的局部与全局
- 关于微信加解密illegal key size问题