【线段树】备用模板

来源:互联网 发布:ae 2017 cc mac破解版 编辑:程序博客网 时间:2024/05/19 02:06


来自学长的线段树模板:



#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){//首先记录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);//找左子树 elseUpDate(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 main(){int n;scanf ("%d",&n);Build(1,1,n);//UpDate(1,1,n,2,7);printf ("%d\n",QuerySum(1,1,n,2,4));return 0;}