线段树【模板】

线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点






#include<stdio.h>
#include<algorithm>
using namespace std;
struct Node
{
	int Sum;	// 和 
	int Max;	//最大值 
	int Min;	//最小值 
	int l;		//左区间 
	int r;		//右区间 
}Tree[4000];
void PushUp(int o)		
{
	Tree[o].Sum = Tree[o*2].Sum + Tree[o*2+1].Sum ;
	Tree[o].Max = max( Tree[o*2].Max , Tree[o*2+1].Max );
	Tree[o].Min  = min( Tree[o*2].Min  , Tree[o*2+1].Min  );	
}
void Build(int o,int l,int r)		//建树 
{
	Tree[o].l=l;	Tree[o].r=r;
	if(l==r)						//到达底层,递归终止。 
	{
		int t;
		scanf("%d",&t);
		Tree[o].Sum = Tree[o].Max = Tree[o].Min = t;
		return ;
	}
	int mid=(l+r)/2;
	Build(o*2,l,mid);
	Build(o*2+1,mid+1,r);
	PushUp(o);
}
void UpDate(int o,int l,int r,int x,int y)		//把节点x的数据更新为y 
{
	if(l==r)
	{
		Tree[o].Max = Tree[o].Min = Tree[o].Sum = y;
		return ;
	}
	int mid=(l+r)/2;
	if(x > mid)			//更新的节点在右边; 
		UpDate(o*2+1,mid+1,r,x,y);
	else			// 节点在左边; 
		UpDate(o*2,l,mid,x,y);
	PushUp(o);		//更新当前节点数据 
}
int	FindSum(int o,int l,int r,int x,int y)	//查找x到y的和
{
	if(l==x && r==y)
	{
		return Tree[o].Sum;
	}
	int mid = (l+r) / 2;
	if(y<=mid)
		return FindSum(o*2,l,mid,x,y);
	else if(x>mid) 
		return FindSum(o*2+1,mid+1,r,x,y);
	else
		return FindSum(o*2,l,mid,x,mid)+FindSum(o*2+1,mid+1,r,mid+1,y);
} 
int	FindMax(int o,int l,int r,int x,int y)
{
	if(l==x && r==y)
	{
		return Tree[o].Max ;
	}
	int mid = (l+r) / 2;
	if(y<=mid)
		return FindMax(o*2,l,mid,x,y);
	else if(x>mid) 
		return FindMax(o*2+1,mid+1,r,x,y);
	else
		return max( FindMax(o*2,l,mid,x,mid), FindMax(o*2+1,mid+1,r,mid+1,y) );
}
int	FindMin(int o,int l,int r,int x,int y)
{
	if(l==x && r==y)
	{
		return Tree[o].Min  ;
	}
	int mid = (l+r) / 2;
	if(y<=mid)
		return FindMin(o*2,l,mid,x,y);
	else if(x>mid) 
		return FindMin(o*2+1,mid+1,r,x,y);
	else
		return min( FindMin(o*2,l,mid,x,mid), FindMin(o*2+1,mid+1,r,mid+1,y) );
}
int main()
{
	int n;
	scanf("%d",&n);
	Build(1,1,n);
	//UpDate(1,1,n,2,7);
	printf("%d\n",FindSum(1,1,n,2,4));
	printf("Max(2~4)%d\n",FindMax(1,1,n,2,4));
	printf("Min(2~4)%d\n",FindMin(1,1,n,2,4));
	return 0;
}
/*
4
1 3 2 6
*/




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值