浅谈线段树
来源:互联网 发布:数据库查询语句讲解 编辑:程序博客网 时间:2024/06/07 16:34
-————终于从数论中爬出来了,没有继续写数论了
点修改
例题:给出一个有n个元素的数组a1,a2,a3,….an,设计一个数据结构,来支持修改某个元素和计算某个区间的最值
分析:因为要修改元素并且要计算最值,就不能再用ST表和遍历整个区间来计算,这两种方法的时间复杂度都较高,且如果一边修改元素,一边找最值,写出的代码就可以直接拿去卡死评测机.
所以我们要引入线段树(又名区间树)这个新的数据结构,而上述的两种问题的解决恰恰是线段树最优美的地方.
如图所示将n个元素由各个结点来储存,如在[5,7]中就可以储存5,6,7之中的最值.而如果要把7这个结点的值修改,则需要把结点[5,7],[1,7],[1,13]这三个结点的值修改.相比起将数组全部遍历,这种方法简单而高效啊.
#include<cstdio>using namespace std;int n; int a[100100]; int minv[101000];int minx(int xxx,int yyy){ if(xxx<yyy) return xxx; else return yyy;}void init(){ scanf("%d",&n); for(int i=1;i<=n;++i){ scanf("%d",&a[i]); }}void hebin(int k){ minv[k]=minx(minv[k<<1],minv[k<<1|1]);}void jianshu(int ql,int qr,int o){ if(ql==qr){ minv[o]=a[ql]; return; } int m=ql+(qr-ql)/2; jianshu(ql,m,o<<1); jianshu(m+1,qr,o<<1|1); hebin(o);}int main(){ init(); jianshu(1,8,1); return 0;}
这是建树的代码,个人比较喜欢用递归实现(像不像快速排序)
下面是先是查询的代码,然后是更新的代码
int ql,qr; //全局变量(查询ql,q2中的最值),这里展示的是最小值 int lookup(int o,int l,int r){ //o表示当前结点编号 int m=l+(r-l)/2,ans=INF; //m这样写是一个小技巧,防止超int(尽量养成这个好习惯) if(ql<=l && r<=qr) return minv[o]; if(ql<=m) ans=minx(ans,lookup(o*2,ql,m)); if(m<qr) ans=minx(ans,lookup(o*2+1,m+1,qr)); return ans;}
int p,v;//将a[p]修改为v
void update(int o,int ql,int qr)
{
int m=ql+(qr-ql)/2;
if(ql==qr) minv[o]=v;
else
{
if(p<=m) update(o*2,ql,m);
else update(o*2+1,m+1,qr);
minv[o]=minx(minv[o*2],minv[o*2+1]);
}
}
阅读全文
1 0
- 浅谈线段树
- 浅谈ZKW线段树
- 浅谈 zkw 线段树
- 浅谈线段树
- 线段树浅谈
- 浅谈线段树
- 浅谈线段树标志下放
- 浅谈线段树 Segment Tree
- 浅谈线段树(Segment Tree)
- 【线段树】浅谈区间问题(1)
- 【线段树】浅谈区间问题(2)
- 【线段树】浅谈区间问题3
- BZOJ2957 浅谈线段树的另类用法
- HDU 4366 浅谈DFS序+线段树
- BZOJ 2243 浅谈树链剖分+线段树
- 浅谈二维中的树状数组与线段树
- BZOJ 4034浅谈树链剖分及线段树维护
- CodeForces 438D 浅谈区间取模线段树
- 我在校招面试中经常遇到的问题
- [2017纪中10-31]Sequence 差分+kmp
- 30天了解30种技术系列---(22) Bootstrap在线编辑器4款
- boost 源码编译和安装 -fPIC
- Ubuntu16.04安装MATLAB R2016b
- 浅谈线段树
- 对于实型数据和整型数据
- linux 批量修改文件名后缀名命令rename
- 解决AndroidStudio 导入项目在 Building gradle project info 一直卡住
- solution_659
- Mysql 利用group by 分组排序
- c#同时上传文件和参数
- pwnable.tw记录之applestore
- GIT学习笔记(5)