线段树初步__ZERO__.
线段树,顾名思义,就是指一个个线段组成的树。
线段树的定义就是:
线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度为O(logN)。
——摘自百度百科
如图,这就是一棵线段树:
那么线段树有哪些神奇的性质呢?
1.它是一棵满二叉树
2.每一个节点(一段区间)是它的两个子节点的并或最大值(RMQ)。
3.(因为线段树是满二叉树)树的空间复杂度是O(4N);
线段树例题
线段树的树结构:
此处我用一个一维的数组seg[node]表示节点为node所划分到的区间的值。
线段树的建树:
因为线段树是一棵满二叉树,所以可以采用递归的方式来实现储存。
void build(int l,int r,int node)
{
if(l==r)seg[node]=a[l];//a[i]表示读入数列的第i个数
else
{
int mid=(l+r)>>;
build(l,mid,node*);
build(mid+,r,node*+);
up(node);//见下
}
return ;
}
Bulid
此处需要介绍一个up(node)函数。
这是用于对这个节点的区间值进行更新。
void up(int node){seg[node]=seg[node*]+seg[node*+];}
Up
建完树,但我们还需要做一些其他的操作,比如说区间查询(区间求和)或区间修改等。
所以我们就先介绍区间查询。
//L、R:目前访问区间的左右节点,ql,qr:查询区间的左右节点,node:当前节点的编号。
int query(int l,int r,int ql,int qr,int node)
{
if(l>=ql&&r<=qr)return seg[node];//①
else
{
int mid=(l+r)>>;
down(mid-l+,r-mid,node);//②
int ans=;
if(ql<=mid)ans+=query(l,mid,ql,qr,node*);//③
if(qr>mid) ans+=query(mid+,r,ql,qr,node*+);
return ans;
}
}
Query
①:因为线段树的节点表示一段区间,所以只要找到访问区间在查询区间内,就可以直接返回这段区间的值,不需要继续递归下去。
②:
{
这是个需要介绍的东西 称为Lazy标记。这是个很重要的东西,线段树的核心之一。
此处需要开一个add[node]数组,表示下标为node的节点需要加上add[node]的Lazy标记。这样就可以完成下放标记的任务。
void down(int l,int r,int node)
{
if(add[node]!=)//KC
{
add[node*]+=add[node];//向左子树下放标记
add[node*+]+=add[node];
seg[node*]+=add[node]*l;//④
seg[node*+]+=add[node]*r;
add[node]=;
}
return ;
}
Down
④:此处的l为上query函数的mid-l+1,为node节点的左子树的区间长度。之所以把 node左子树+Lazy标记*左子树区间长度 是因为每一个叶节点都需要加上此节点的Lazy标记。r处同上。
}
③:这需要解决的是为什么ql≤mid就可以直接ans+=query(node*2)。这主要是因为我们接下去寻找的是当前L~Mid区间里的在查询范围内的节点,因为ql≤mid无非就两种情况,l<ql或l≥ql且r在此情况下都大于等于ql,又因为每次return回来的一定是查询区间范围内的值,所以只要ql≤mid就可以了。qr>mid同上。
下面是区间修改;
//v为区间内修改(增加或减少)的值
void change(int l,int r,int ql,int qr,int node,int v)
{
if(l>=ql&&r<=qr)
{
seg[node]+=v*(r-l+);//①
add[node]+=v;//①
return ;
}
else
{
int mid=(l+r)>>;
down(mid-l+,r-mid,node);
if(ql<=mid)change(l,mid,ql,qr,node*,v);
if(qr>mid) change(mid+,r,ql,qr,node*+,v);
up(node);//②
}
}
Change
①:如果访问区间已经在修改区间内,就可以直接修改node节点的值,并在node节点处留下标记,等着下一次询问或修改的时候做下放标记的操作。r-l+1为访问区间的长度。
②:因为此处为修改操作,需要进行up函数来更新。
线段树初步__ZERO__.的更多相关文章
- 线段树初步——转载自ljc20020730
线段树初步 线段树模板1:https://www.luogu.org/problem/show?pid=3372 线段树模板2:https://www.luogu.org/problem/show ...
- 线段树初步&&lazy标记
线段树 一.概述: 线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点. 对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a, ...
- 线段树分治初步学习&洛谷P5227[AHOI2013]连通图
线段树分治 其实思想说起来是比较简单的,我们把这个题里的所有操作(比如连边删边查询balabala)全部拍到一棵线段树上,然后对着整棵树dfs一下求解答案,顺便把操作做一下,回溯的时候撤销一下即可.虽 ...
- 【BZOJ-3779】重组病毒 LinkCutTree + 线段树 + DFS序
3779: 重组病毒 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 224 Solved: 95[Submit][Status][Discuss] ...
- 线段树(单点更新)HDU1166、HDU1742
在上一篇博文里面,我提到了我不会线段树,现在就努力地学习啊! 今天AC一题感觉都很累,可能是状态不佳,在做HDU1166这题目时候,RE了无数次. 原因是:我的宏定义写错了,我已经不是第一犯这种错误了 ...
- Luck and Love(二维线段树)
Luck and Love Time Limit: 10000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tota ...
- poj_2528Mayor's posters(线段树)
poj_2528Mayor's posters(线段树) 标签: 线段树 题目连接 Mayor's posters Time Limit: 1000MS Memory Limit: 65536K To ...
- BZOJ4695 最假女选手(势能线段树)
BZOJ题目传送门 终于体会到初步掌握势能分析思想的重要性了. 一开始看题,感觉套路还是很一般啊qwq.直接在线段树上维护最大值和最小值,每次递归更新的时候,如果不能完全覆盖就暴力递归下去.挺好写的欸 ...
- 【洛谷P4097】Segment 李超线段树
题目大意:维护一个二维平面,给定若干条线段,支持询问任意整数横坐标处对应的纵坐标最靠上的线段的 id,相同高度取 id 值较小的,强制在线. 题解:初步学习了李超线段树.李超线段树的核心思想在于通过标 ...
随机推荐
- 【踩坑】activiti工作流的svg-xml解析报错
1.问题记录 工作流配置画模板的时候保存成功但是部署报错. IE下 activiti工作流解析xml报错 type "path" must be followed by eithe ...
- 有了 indexOf,为什么 ECMAScript 7 还添加了 Array.prototype.include
ECMAScript 7 中新增了用于检测数组中是否包含某个元素 Array.prototype.includes() API,想到了 Array 其实有很多相关 API 可以检测到是否包含某个元素, ...
- Spring中AOP简介与切面编程的使用
Spring中AOP简介与使用 什么是AOP? Aspect Oriented Programming(AOP),多译作 "面向切面编程",也就是说,对一段程序,从侧面插入,进行操 ...
- Error Handling in ASP.NET Core
Error Handling in ASP.NET Core 前言 在程序中,经常需要处理比如 404,500 ,502等错误,如果直接返回错误的调用堆栈的具体信息,显然大部分的用户看到是一脸懵逼的 ...
- CSS 中的 initial、inherit、unset、revert
在css中,initial(初始).inherit(继承).unset(未设置).revert(还原)这四个关键字可以应用于所有的CSS属性. initial - 初始默认值.IE不支持 inheri ...
- PHP(函数)
<script> // 获得日 var time = new Date(); var x = time.getDate(); document.write(x+"日," ...
- JAVA中String = null 与 String = "" 的区别
JAVA中String = null 与 String = ""的区别 笔者今天在Debug的时候发现的NPE(NullPointerException),辛辛苦苦地调试了半天,终 ...
- 201521123100 《Java程序设计》 第1周学习总结
1. 本章学习总结 1.简单了解学习了Java及其开发环境,学习使用了Notepad++&eclipse开发软件的使用 2.熟练完成了使用Notepad++运行第一个Java程序"H ...
- JAVA2015086第十一周作业
本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结多线程相关内容. 书面作业 本次PTA作业题集多线程 1.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了 ...
- 201521123116 《java程序设计》第十周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 Q1 finally 题目4-2 1.1 截图你的提交结果(出现学号) 1.2 4-2中fi ...