【线段树模板】
来源:互联网 发布:阿里云服务器地域选择 编辑:程序博客网 时间:2024/06/05 18:24
/* 一个节点下标为o,它的左孩子的下标等于 o*2 , 右孩子等于o*2+1,左孩子区间【1,o*2】,右孩子区间【o*2+1,n】 */#include<cstdio>#include<algorithm>using namespace std;#define L o<<1#define R (o<<1)|1struct Node{ int l,r,sum,Max,Min;}Tree[1000<<2];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)//建树,o为下标,l,r为区间 ,用递归首先想出来递归结束条件 { //首先记录l和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) >> 1; //找到中间节点 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,l,mid,x,y); //找左子树 else UpDate(o*2+1,mid+1,r,x,y); //找右子树 PushUp(o); //更新当前节点 }int QuerySum(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 (mid >= y) //全在左边 return QuerySum(o*2,l,mid,x,y); else if (x > mid) //全在右边 return QuerySum(o*2+1,mid+1,r,x,y); else //一半在左一半在右 return QuerySum(o*2,l,mid,x,mid) + QuerySum(o*2+1,mid+1,r,mid+1,y);}int QueryMax(int o,int l,int r,int x,int y)//查找x到y之间的最大值 { if(l==x&&r==y) { return Tree[o].Max ; } int mid=(l+r)>>1; if(mid>=y) { return QueryMax(o*2,l,mid,x,y); } else if(x>mid) return QueryMax(o*2+1,mid+1,r,x,y); else return max(QueryMax(o*2,l,mid,x,mid),QueryMax(o*2+1,mid+1,r,mid+1,y));}int QueryMin(int o,int l,int r,int x,int y)//查找x到Y之间的最小值 { if(l==x&&r==y) { return Tree[o].Min ; } int mid=(l+r)>>1; if(mid>=y) { return QueryMin(o*2,l,mid,x,y); } else if(x>mid) return QueryMin(o*2+1,mid+1,r,x,y); else return min(QueryMin(o*2,l,mid,x,mid),QueryMin(o*2+1,mid+1,r,mid+1,y));}int main(){ int n,m; scanf ("%d",&n); Build(1,1,n);// UpDate(1,1,n,2,7); printf ("%d\n",QuerySum(1,1,n,2,4)); printf ("%d\n",QueryMax(1,1,n,2,4)-QueryMin(1,1,n,2,4));// printf ("%d\n",QueryMin(1,1,n,2,4)); return 0;}
阅读全文
0 0
- ACM 线段树模板(模板)
- 线段树模板
- hdu_1166_线段树模板
- 线段树模板
- 线段树模板 poj2777
- 线段树模板
- 线段树模板
- 线段树-模板
- 线段树模板
- 线段树模板
- 线段树模板
- Hdu1166-- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- 线段树模板
- java基础——XML、正则表达式、反射机制
- java面试基础
- 线段树总结
- 2.Android灯光系统_源码分析_电池灯
- 神经网络理解(一)
- 【线段树模板】
- java初识之旅
- SVN-集中式版本控制系统
- 1410: QAQ & 火星情报局 [数学]
- codeforces822D (86/600)
- oracle中常用函数大全
- css3 实现自由摆动的立方体
- 3.Android灯光系统_源码分析_通知灯
- C#版本号管理