线段树之建树,单点更新以及区间查询
来源:互联网 发布:软件许可使用权证书 编辑:程序博客网 时间:2024/06/05 02:19
线段树之建树,单点更新以及区间查询
线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。
使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。而未优化的空间复杂度为2N,因此有时需要离散化让空间压缩。
在这篇文章中,我们就主要讲一下最基础的线段树的创建,单点更新以及区间查询。当然具体操作是以区间和的形式讲解,当遇到其他题目如求最大值或最小值时,只需要修改一部分就行了,思想都是一样的。
在贴代码之前我想说一下自己关于线段树操作的一些细节,可以说在大多关于线段树讲解的书上,建树的时候总是喜欢先开一个结构体来储存信息,这倒没什么,关键是还要定义两个变量来记录该节点的左右区间的端点,个人觉得这非常没有必要,本来建树开数组的时候大小要为当前给你得点数的4倍,并且在ACM竞赛中点数的数量级非常大,再去定义两个变量浪费了很多空间,关于区间的端点问题,可以在函数的参数列表中做为参数传下去,这样就不用再额外开空间来储存这两个变量了。
下面将用代码来解释相关的操作,有注释作为说明,这只是作为借鉴用处,如果有不对的地方还请留言,共同进步。
const int maxn=10005;//点的个数int tree_sum[maxn<<2]//建立大小为点个数4倍的数组来储存该区间的和//建树操作void bulid_tree_sum(int root,int l,int r)//root表示该节点的下标值,l、r分别表示区间的左右端点{ if(l==r)//如果是叶子节点,就赋值 { cin>>tree_sum[root]; return ; } int mid=(l+r)>>1; build_tree_sum(root<<1,l,mid);//建立左儿子 build_tree_sum(root<<1|1,mid+1,r);//建立右儿子 tree_sum[root]=tree_sum[root<<1]+tree_sum[root<<1|1];//更新父亲节点}//单点更新操作void update(int root,int l,int r,int pos,int val)//pos表示区间的哪个点有更新,val表示更新后的值{ if(l==r&&l==pos)//如果找到该叶子节点就更新 { tree_sum[root]=val; return ; } int mid=(l+r)>>1; if(pos<=mid) update(root<<1,l,mid,pos,val);//如果满足条件查找左儿子 else update(root<<1|1,mid+1,r,pos,val);//否则查找右儿子 tree_sum[root]=tree_sum[root<<1]+tree_sum[root<<1|1];//同时更新父亲节点}//区间和查询操作int query(int root,int l,int r,int L,int R)//L,R分别表示要查询的区间的左右端点{ if(L<=l&&r<=R)//如果所求区间包含该节点所表示的区间就返回该区间的和,不用再去访问他的儿子节点 { return tree_sum[root]; } int mid=(l+r)>>1,sum=0; if(L<=mid)//如果所求区间有一部分在该节点左儿子的范围内,就查询左儿子 sum+=query(root<<1,l,mid,L,R); if(mid<R) sum+=query(root<<1|1,mid+1,r,L,R);//如果所求区间有一部分在该节点右儿子的范围内,就查询右儿子 return sum;}
0 0
- 线段树之建树,单点更新以及区间查询
- [模板]线段树的建树、查询、单点更新、区间更新
- HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)
- zoj (单点更新区间查询:线段树)
- 线段树单点更新和区间查询
- hdu1166(线段树单点更新区间查询)
- hdu5316 Magician (线段树+单点更新+区间查询+区间合并)
- 线段树(堆式)[单点更新, 区间查询]
- hdoj 4339 线段树 单点更新,区间查询
- HDU 2795 线段树(单点更新 区间查询)
- HDOJ3016Man Down(线段树(区间更新,单点查询)+DP)
- HDU1754线段树单点更新区间查询(数组版)
- Necklace (线段树单点更新+区间查询+离线操作)
- HDU 4819:单点更新,区间查询的二维线段树
- hdu 4046 Panda (线段树 单点更新 区间查询)
- POJ 3264 Balanced Lineup (线段树单点更新 区间查询)
- Flipping Parentheses (线段树 单点更新 区间查询)
- 【单点更新,区间查询,线段树】【HDU1166】【敌兵布阵】
- 数据仓库基础术语名词一览
- 高吞吐量系统设计优化建议
- poj 1089 Intervals
- 2015Kali渗透技术教程
- 2015Kali渗透技术教程
- 线段树之建树,单点更新以及区间查询
- 2015Kali渗透技术教程
- NYOJ 214 单调递增子序列(二)
- Architectural Tradeoffs
- LeetCode:Two Sum
- 企业讲座
- 企业讲座
- 企业讲座
- C++STL位标志、智能指针与异常处理