线段树听课学习笔记

一.线段树的引入

做题的时候遇到了BMQ问题,就是求给定区间中的最大值最小值问题,暴力搜索只限于数据范围较小,控制在1000-10000左右的时候。而线段树解决了O(nlogn)的时间复杂度,其中建树为O(n).

二.线段树的性质

1.平衡二叉树,最大深度为logn
2.树中每一个节点代表一个区间(叶子节点是一个点)
3.每个节点完全包含他的所有子孙节点
4.任意两个节点要么是完全包含,要么互不相交
5.在进行区间操作和统计时把区间等价转换为若干个子区间的相同操作

三.区间和例子

#include<iostream>
using namespace std;
#define Maxn 1100
int tree[4*Maxn];
int a[Maxn];
void build(int p,int l,int r)   //建树 
{
	if(l==r)
	{
		tree[p]=a[l];//a[r]也可以
		return ;
	}
	int mid=(l+r)/2;
	build(2*p,l,mid);
	build(2*p+1,mid+1,r);
	tree[p]=tree[2*p]+tree[2*p+1];//这一句可以根据题面发生改变,这里是区间和。 
}
void change(int p,int l,int r,int x,int num)   //修改a数组里x节点,修改为num 
{
	if(l==r) 
	{
		tree[p]=num;
		return ;
	}
	int mid=(l+r)/2;
	else if(x<=mid) change(2*p,l,mid,x,num);
	else change(2*p+1,mid+1,r,x,num);
	tree[p]=tree[2*p]+tree[2*p+1];//返回的时候递归修改 
}
int find(int p,int l,int r,int x,int y)
{
	if(x<=l&&r<=y) return tree[p];
	int mid=(l+r)/2;
	if(y<=mid) return find(2*p,l,mid,x,y);
	if(x>mid) return find(2*p+1,mid+1,r,x,y);
	return find(2*p,l,mid,x,mid)+find(2*p+1,mid+1,r,mid+1,y);
}

四. 线段树关键

需要维护哪些区间信息,怎样去维护这个信息

五.懒标记(lazy)与线段树

选自牛客网竞赛辅导

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值