线段树小结


所谓线段树, 就是一种支持在线更新和查询的数据结构, 建树的时间复杂度为O(nlogn), 而大多数情况能保证每次查询的复杂度为O(logn), 搞笑快速。


建树:



大概就是这样, 每个区间都有一个父节点, 设父节点下标为rt, 区间为[l, r], rt存的是该区间内的信息;

当 l == r时, rt代表下标为l的单点信息。rt的左孩子下标为rt << 1, 右孩子为rt << 1|1;


左孩子区间:[l, (l + r) >> 1]

右孩子区间:[((l + r) >> 1) + 1, r] 


所以, 大致用到的空间为2 *n - 1(n位数据量), 但是一般开到4倍的空间比较稳。


建树的代码:

void pushUp(int rt) {									//用孩子更新父节点信息
	//code
}
void build(int rt, int l, int r) {						//rt为当前节点, [l , r]为区间

	if (l == r) {
		//code                                          //找到单点初始化,返回
		return;
	}

	int mid = (l + r) >> 1;
	build(rt << 1, l, mid);								//未找到单点递归左孩子, 右孩子建树
	build(rt << 1 | 1, mid + 1, r);
	pushUp(rt);
}


而后为了方便, 一般用宏写节点和区间,即:

#define mid ((l + r) >> 1)
#define ls rt << 1, l, mid
#define rs rt << 1|1, mid + 1, r

void pushUp(int rt) {									//用孩子更新父节点信息
	//code
}


void build(int rt, int l, int r) {						//rt为当前节点, [l , r]为区间

	if (l == r) {
		//code                                          //找到单点初始化,返回
		return;
	}
	build(ls);								//未找到单点递归左孩子, 右孩子建树
	build(rs);
	pushUp(rt);
}

更新和查询, 和建树类似, 找到区间, 在更新, pushUp;


有待更新....先去上课





 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值