线段树的建树 单点修改 区间查询

(未经允许,严禁抄袭转载)(若有错误,请多多指教)
在这里插入图片描述看了这张图后,大家可能明白建树的意思了
看代码以及注释

#include<bits/stdc++.h>
using namespace std;
void build(int ll,int rr,int num){
//表示当前为第num号区间[ll,rr] 
	e[num].l=ll,e[num].r=rr;
	if(ll==rr){//即该区间只有一个叶节点 
		//e[num].maxx=a[ll];
		//e[num].sum=a[ll];		
		return;//此处看题需要什么,连接表存
	}
	int mid=(ll+rr)>>1;
	build(ll,mid,num*2);//左子树 
	build(mid+1,rr,num*2+1);//右子树
	//e[num].maxx=max(e[num*2].maxx,e[num*2+1].maxx) 引题而异 
}
//建树的实质为将一段长区间分成若干个小区间
//维护会很方便 
int main(){
	build(1,n,1);
	return 0;
}

线段树建树到此就学完了
是不是非常清晰,明白

接下来是单点修改
很简单
代码注释能看懂就学会了
第一行是总结,可以最后看

//我们主要是来寻找这个点在哪,然后找到这个点所在区间长为1
//这样便于修改,我们只需要知道,每次的q在左子树还是右子树即可 
#include<bits/stdc++.h>
using namespace std;
void update(int q,int x,int ll,int rr,num){
//将第q号节点增加(变为)x当前我们寻找到第num区间,左端点为ll,右端点为rr 
	if(ll==rr){//既找到该点所在的叶节点 
		a[num]+=x;//a[num]=x;
		//e[num].maxx=a[num];
		return;
	}
	int mid=(ll+rr)>>1;
	if(q<=mid) update(q,x,ll,mid,num*2);
	else update(q,x,mid+1,rr,num*2+1);
	//可更新maxx,sum等等 
	//此处必须与建树对应
	//如:q<=mid 因为该点在左子树上,mid为该区域端点 
}
int main(){
	update(q,x,1,n,1);
	return 0;
}

个人认为已经解释清楚了
最后一个:区间查询
在这里插入图片描述图片上的字会帮助你理解

#include<bits/stdc++.h>
using namespace std;
int query(int L,int R,int ll,int rr,int num){
//分别表示需要查询的区间[L,R],以及正在查询的区间编号为num,[ll,rr];
	if(l>=L && r<=R)//正在查询的区间在需要查询区间内 
		return e[num].sum;
	int mid=(l+r)>>1;
	int ans=0;
	if(L<=mid) ans+=query(L,R,l,m,num*2);
	if(R>mid) ans+=query(L,R,mid+1,r,num*2+1);
	//右子树与要查询区间有重叠 
	//此处可能两个都走 
	return ans;
} 
int main(){
	query(ll,rr,1,n,1) 
	return 0;
} 

今天要讲的内容已经结束了
如果想要了解更多,可以学一下区间加值以及区间修改
如果有问题,请不吝赐教
祝大家一切顺利
再见!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值