线段树

本文详细介绍了线段树这种数据结构,包括其在区间加、区间查询上的高效操作,以及与差分序列和树状数组的比较。通过线段树的标准代码实现,展示了如何进行区间和的查询和更新,并提供了完整的C++代码示例。文章适合初学者入门,通过观看推荐的视频教程可以更好地理解线段树的工作原理。
摘要由CSDN通过智能技术生成


算法预处理区间加询问区间和
差分序列o(n)o(1)o(n)
树状数组o(nlogn)o(n)o(1)
线段树o(n)o(n)o(log n)

线段树

不懂线段树的直接看b站大佬视频:https://www.bilibili.com/video/BV1cb411t7AM?from=search&seid=7095115582360789450

线段树标准代码

#include<stdio.h>
const int N=1e5+10;
int a[N],tree[4*N]={0};

// 查询区间[L,R]的区间数值之和 
int query_tree(int node,int start,int end,int L,int R){
	if(R<start||L>end) return 0;
	else if(L<=start&&end<=R) return tree[node];
	else if(start==end) return tree[node];
	int mid=(start+end)/2;
	int left_node=2*node+1,right_node=2*node+2;
	int sum_left=query_tree(left_node,start,mid,L,R);
	int sum_right=query_tree(right_node,mid+1,end,L,R);
	return sum_left+sum_right;
}

// 把数组a的下标为 idx的值改为val 
void update_tree(int node,int start,int end,int idx,int val){
	if(start==end){
		tree[node]=val;
		return ;
	}
	int mid=(start+end)/2;
	int left_node=2*node+1,right_node=2*node+2;
	if(idx>=start&&idx<=mid) update_tree(left_node,start,mid,idx,val);
	else update_tree(right_node,mid+1,end,idx,val);
	tree[node]=tree[left_node]+tree[right_node];
} 

//建树
void build_tree(int node,int start,int end){
	if(start==end){
		tree[node]=a[end];
		return ;
	}
	int mid=(start+end)/2;
	int left_node=2*node+1,right_node=2*node+2;
	build_tree(left_node,start,mid);
	build_tree(right_node,mid+1,end); 
	tree[node]=tree[left_node]+tree[right_node];
}
int main(){
	int n,q,l,r;
	scanf("%d%d",&n,&q);
	for(int i=0;i<n;i++) scanf("%d",&a[i]);
	build_tree(0,0,n-1);
	for(int i=0;i<q;i++){
		scanf("%d%d",&l,&r);
		printf("%d\n",query_tree(0,0,n-1,l,r));
	}
} 

总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值