线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点
#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
*/