线段树(二)区间最值
2016-10-10 15:01
176 查看
区间最值
区间求最值是简单的线段树问题,区间最值也可以用ST表求得,具体问题具体分析.思想
考虑建树
递归建树,叶节点的最值就是当前节点表示的值
除叶节点外的其他节点最值等于Max(左儿子,右儿子)或是Min(左儿子,右儿子);
给出某个区间后将这个区间分到很多子区间快速求解
举个栗子,还是上一节的[1,10]的树,现在询问[4,7]的最值
由于左右儿子是根据Mid分开的,所以在分配问题时也需要考虑Mid和给定区间的关系
1.左端点大于Mid
代表整个区间在右儿子上,只需询问右儿子
2.右端点小于Mid
代表整个区间在左儿子上,只需询问左儿子
3.跨越左右儿子
在左右儿子的最值取Max或Min
递归可求解,复杂度NlogN
代码
#include<cstdio> #include<iostream> #include<iostream> using namespace std; const int Maxn=100001; #define mid (l+r)/2 #define lc o<<1 #define rc (o<<1)+1 struct node{int mi;}point[Maxn*4]; int t,n,x,y,a[Maxn]; int query(int l,int r,int o,int x,int y) { if(l==r)return point[o].mi; if(x==l&&y==r) return point[o].mi; else if(y<=mid) return query(l,mid,lc,x,y); else if(x>mid) return query(mid+1,r,rc,x,y); else return min(query(l,mid,lc,x,mid),query(mid+1,r,rc,mid+1,y)); } void build(int l,int r,int o) { if(l==r){point[o].mi=a[l];return;} build(l,mid,lc); build(mid+1,r,rc); point[o].mi=min(point[lc].mi,point[rc].mi); return; } int main() { scanf("%d%d",&n,&t); for(int i=1;i<=n;i++)scanf("%d",&a[i]); build(1,n,1); for(int i=1;i<=t;i++) { scanf("%d%d",&x,&y); printf("%d ",query(1,n,1,x,y)); } }
区间最大值把Min操作改成Max即可
End。
相关文章推荐
- hdu 4578 Transformation(线段树中级,区间和加强)
- 线段树 : 区间更新 poj 3468 示例
- hdoj 1556 Color the ball 【线段树 + lazy区间更新】 【树状数组】
- HDOJ 2871 Memory Control(线段树区间合并与查询)
- POJ - 3162 Walking Race 【树上最远距离 + 线段树处理区间最值 + 尺取法 】
- hdu 1540 线段树区间合并
- POJ 2892 Tunnel Warfare(线段树区间合并与查询)
- HDU - 1698 D - Just a Hook (线段树区间更新)
- Just a Hook +线段树区间更新模板题
- 线段树 区间求和 poj 3468 A Simple Problem with Integers
- 【POJ 3368】【RMQ 或者 线段树】Frequent values【求出区间内连续出现次数最多的数的次数。】
- HDU 5893 List wants to travel (树链剖分,线段树区间合并)
- kb-07线段树-12--二分查找区间边界
- 线段树区间更新Thermal Death of the Universe
- HDU 1754 线段树单点更新 区间最值
- 3226: [Sdoi2008]校门外的区间 线段树
- kuangbin专题七 : B题 :HDU 1754 I Hate It(线段树单点更新区间查询最值)
- Uva 11992 Fast Matrix Operations(线段树区间设值与加操作)
- FOJ 2171 防守阵地 II【线段树+区间更新】
- 【HDU - 1540】Tunnel Warfare 【线段树+单点更新+区间合并】