线段树简述
来源:互联网 发布:linux压缩成zip 编辑:程序博客网 时间:2024/06/08 20:09
线段树是一棵二叉搜索树,常用于解决区间问题。
线段树每一个非叶子节点[left,right],它的左二子区间[left,(left+right)/2],右儿子区间[(left+right)/2+1,right]。
线段树的结构体,内元素包括,此节点包含区间[left,right],和value
//线段树结构体 #include <bits/stdc++.h> using namespace std; const int maxn = 1<<20; const int N; struct Node { int value; //检点区间权值 int left, right; //区间(left,right) }node[maxn]; int father[N]; //每个点(当区间长度为0时,对应的结构体数组下标)
线段树的建立
void BuildTree(int i, int left, int right) { node[i].left = left; //写入第i个结点的左区间 node[i].right = right; //写入第i个结点的右区间 node[i].value = 0; //区间权值初始化为0 if(left == right) { father[left] = i; //知道每个点对应的序号(结点的下标) return; } //建立左子树 BuildTree(i<<1, left, (left+right)/2); //建立右子树 BuildTree((i<<1)+1, (left+right)/2+1, right); }
单点更新线段树
因为事先用father[]数组保存过每个节点对应的的下标,因此只要知道第几个点,就知道这个点在树中的位置(即下标),这样就只要一路向上更新上去即可。
void UpdateTree(int r1) { if(r1 == 1) return; //已找到祖先 int fi = r1/2; //ri的父节点 int a = node[fi<<1].value; //该父节点的两个孩子 int b = node[(fi<<1)+1].value; //右 node[fi].value = (a > b) ? a : b; UpdateTree(ri/2); //递归更新,有父节点往上找 }
查询区间最大值
讲一段区间从上往下拆开,直到存在有完全重合的区间停止。
int Max = -1<<20; void Query(int i, int l, int r) { if(node[i].left == l && node[i].right == r) { Max = (Max < node[i].value) ? (node[i].value) : (Max); return; } i = i << 1; if(l <= node[i].right) { //左区间有涉及 if(r <= node[i].right) //全包含于左区间,则查询形态不变 Query(i, l, r); else //半包含于左区间,则查询区间拆分,左端点不变,右端点变为左区间的右孩子端点 Query(i, l, node[i].right); } i += 1; if(r >= node[i].left) { //右区间有涉及 if(l >= node[i].left) //全包含于右区间,则查询形态不变 Query(i, l, r); else //半包含于右区间,则查询区间拆分 Query(i, node[i].left, r); } }
阅读全文
0 0
- 线段树简述
- 线段树?线段树!
- 线段树?线段树!
- 设备树简述
- 线段_线段树
- 线段_线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- 线段树
- pycharm最常用快捷键总结(mac)
- MySQL数据库使用——MySQL表管理
- 【牛腩新闻发布系统】改变表格的内容
- Vuejs全家桶系列(一)--- 基本用法
- Android中调用第三方实现美团城市选择
- 线段树简述
- JQuery 设置样式属性
- 数据结构上机-迷宫-非递归版深度优先搜索
- PHP WebShell变形技术总结
- python基础(03)——while循环和for循环
- JS原生DOM笔记
- Tablayout的应用
- spring整合jdbc
- 写一个功能类似字符串title()方法的函数