线段树的应用(最大值,区间求和)
2012-04-29 20:15
288 查看
//线段树中不是懒方法建立,修改(某个数据),查询区间和(sum)与最大值(max) #include<cstdio> #include<iostream> using namespace std; const int MAXN=1000; struct { int left,right; //区间的端点 int max,sum; //视题目要求而定 } tree[MAXN*4] ; int a[MAXN]={0,1,2,3,4,5,6,7,8,9,10} ;//仅用于实验 int max(int a,int b) { return a>b?a:b; } void build(int id,int l,int r) { tree[id].left=l; tree[id].right=r; if (l==r)//已到达叶子 { tree[id].sum=tree[id].max=a[l];//在根结点上,sum,max 的结果相等,都为a[l]本身 //tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; // tree[id].max=max(tree[id*2].max,tree[id*2+1].max); return; } else { int mid=(l+r)/2; build(id*2,l,mid); build(id*2+1,mid+1,r); tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; tree[id].max=max(tree[id*2].max,tree[id*2+1].max); } } void update(int id,int pos,int val)//此外为将第pos个数改为val { if (tree[id].left==tree[id].right) { tree[id].sum=tree[id].max=val; } else { int mid=(tree[id].left+tree[id].right)/2; if (pos<=mid) update(id*2,pos,val);//更新左子树 else update(id*2+1,pos,val);//更新右子树 tree[id].sum=tree[id*2].sum+tree[id*2+1].sum; tree[id].max=max(tree[id*2].max,tree[id*2+1].max); } } int query(int id,int l,int r) //这是查询总和的函数 { if (tree[id].left==l&&tree[id].right==r) return tree[id].sum; //询问总和 else { int mid=(tree[id].left+tree[id].right)/2; if (r<=mid) return query(id*2,l,r); else if (l>mid) return query(id*2+1,l,r); else return query(id*2,l,mid)+query(id*2+1,mid+1,r); } } int query_max(int id,int l,int r) { if(tree[id].left==l&&tree[id].right==r) { return tree[id].max; } else { int mid=(tree[id].left+tree[id].right)/2; if(r<=mid) return query_max(id*2,l,r); else if(l>mid) return query_max(id*2+1,l,r); else return query_max(id*2,l,mid)+query_max(id*2+1,mid+1,r); } } int main() { int n=10; build(1,1,n); // printf("%d\n",query(1,1,10)); cout<<query_max(1,1,10)<<endl; update(1,3,15); cout<<query_max(1,1,10)<<endl; }
本文出自 “与谁争峰” 博客,请务必保留此出处http://wwwacm.blog.51cto.com/3014849/847405
相关文章推荐
- 线段树区间更新,区间求和,最大值,最小值模板
- 蓝桥杯算法训练——操作格子(线段树+单点更新+区间求和+求最大值)
- 线段树求区间最大值+区间更新+区间求和+lazy标记
- poj 3468(线段树应用:区间求和)
- HDU1698 Just a Hook(线段树成段替换、区间求和,延迟标记的应用)
- 线段树 (区间查询最大 区间求和 区间加)带lazy
- 线段树部分总结 (单点,区间)更新,区间求和,求最大值(敌兵布阵&I Hate It&A Simple Problem with Integers)
- 线段树的建立与应用---区间求和
- 线段树---poj3468 A Simple Problem with Integers:成段增减:区间求和
- POJ3264(线段树求区间最大值和最小值)
- SPOJ 1043 Can you answer these queries I 求任意区间最大连续子段和 线段树
- HDU 1166-敌兵布阵(线段树:单点更新,区间求和)
- CDOJ1073-秋实大哥与线段树 线段树单点更新+区间求和
- poj3468 线段树区间更新,区间求和
- poj 2828 Buy Tickets 【线段树】【逆序插入 + 单点更新 + 区间求和】
- POJ3468 A Simple Problem with Integers(线段树成段增减,区间求和)
- hdu 1754 线段树区间最大值 单点更新
- LightOJ 1164 Horrible Queries 线段树区间更新求和
- hdu 1698 Just a Hook(线段树区间更新求和)
- hdu 1166 敌兵布阵【线段树,单点增减,区间求和】