线段树总结
来源:互联网 发布:淘宝货款什么时候解冻 编辑:程序博客网 时间:2024/05/16 06:30
初识线段树,线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶子节点。使用线段树可以快速的查找某一个节点在若干条线段中出现的次数,时间复杂度O(logN)。而未优化的时间复杂度为2N,因此有时需要离散化让空间压缩。
对于线段树中的每一个非叶子节点[a,b],它的左儿子表示的区间为[a,(a+b)/2],右儿子表示的区间为[(a+b)/2+1,b]。线段树是平衡二叉树,最后的子节点数目为N,即整个线段区间的长度。
线段树基本操作:
建立一个结构体
struct
{
int l,r,sum;
}t[140000];
int summ;
定义线段树的构造函数:
void make(int left,int right,int num)//创建线段树 { t[num].l=left; t[num].r=right; if(left==right) t[num].sum=r[left]; else { make(left,(left+right)/2,num+num); make((left+right)/2+1,right,num+num+1); t[num].sum=t[num+num].sum+t[num+num+1].sum; }}
查询:
void query(int left,int right,int num)//查找范围内父节点的和 { if(left<=t[num].l&&right>=t[num].r) SUM+=t[num].sum; else { if(right<=(t[num].l+t[num].r)/2) query(left,right,num+num); else if(left>=(t[num].l+t[num].r)/2+1) query(left,right,num+num+1); else { query(left,right,num+num); query(left,right,num+num+1); } }}
添加:
void add(int x,int y,int num)//修改每一个包括改变的那个数的节点 { t[num].sum+=y; if(t[num].l==t[num].r) return ; if(x>(t[num].l+t[num].r)/2) add(x,y,num+num+1); else add(x,y,num+num);}
减少:
void sup(int x,int y,int num){ t[num].sum-=y; if(t[num].l==t[num].r)return ; if(x>(t[num].l+t[num].r)/2) sup(x,y,num+num+1); else sup(x,y,num+num);}
阅读全文
0 0
- 线段树总结
- 简单线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树总结
- 线段树 总结
- 线段树总结
- 线段树最后总结
- 线段树总结
- 线段树_总结
- 线段树总结
- 代码中特殊的注释技术——TODO、FIXME和XXX的用处
- MQTT-SN协议阅读之MQTT-SN Architecture
- BZOJ1588 洛谷2234 HNOI2002营业额统计
- Delphi 7 编译时出现 Internal error U1295 错误时的处理一例
- WordPress——SiteOrigin设置一行中的Widgets竖直居中显示
- 线段树总结
- Servlet Context
- Hibernate中的检索策略
- 双击直接修改内容的js代码
- hdu 6092 Rikka with Subset 背包(贪心)
- OOP设计
- 设计模式之策略模式
- 股票买卖
- 金融类数据测试与监控实践