线段树【模板】

来源:互联网 发布:js dom css样式 编辑:程序博客网 时间:2024/06/07 22:03

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






#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);//更新当前节点数据 }intFindSum(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);elsereturn FindSum(o*2,l,mid,x,mid)+FindSum(o*2+1,mid+1,r,mid+1,y);} intFindMax(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);elsereturn max( FindMax(o*2,l,mid,x,mid), FindMax(o*2+1,mid+1,r,mid+1,y) );}intFindMin(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);elsereturn 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;}/*41 3 2 6*/




原创粉丝点击