(线段树) 单点更新,区间查询最值
Posted 0一叶0知秋0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(线段树) 单点更新,区间查询最值相关的知识,希望对你有一定的参考价值。
/* 单点更新,区间查询最值 */
/* 注意线段树的大小要比需要使用线段树的数据的个数 大3到4倍 */
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> using namespace std ; #define maxn 4000001 struct node { int le , ri ; int num ; }; node tree[maxn*4] ; int a[maxn] ; int n , m ; char ch ; int x , y ; void build(int root , int l , int r){ if(l == r){ tree[root].le = tree[root].ri = l ; tree[root].num = a[l] ; return; } tree[root].le = l ; tree[root].ri = r ; int mid = (l + r) /2 ; build(root*2 , l , mid) ; build(root*2+1 , mid + 1 , r) ; tree[root].num = max(tree[root*2].num , tree[root*2+1].num) ; } // 单点更新 (二叉查询) void update(int root , int pos , int value ){ if(tree[root].le == pos && tree[root].ri == pos){ tree[root].num = value ; return; } int mid = (tree[root].le + tree[root].ri)/2 ; if(pos <= mid){//(二叉查询) update(root*2 , pos , value) ; } else { update(root*2+1 , pos , value) ; } tree[root].num = max(tree[root*2].num , tree[root*2+1].num) ; } //查询区间【start,end】中的最大值 int query(int root , int start , int ends){ if(tree[root].le == start && tree[root].ri == ends){ return tree[root].num ; } int mid = (tree[root].le + tree[root].ri)/2 ; //[start,mid] (mid , ends] . if( mid < start ){ return query(root*2+1 , start , ends) ; } else if(ends <= mid ){ return query(root*2 , start , ends) ; } else if( start <= mid && mid < ends){ return max(query(root*2 , start , mid) , query(root*2+1 , mid+1 , ends) ) ; } } int main(){ while(~scanf("%d%d" , &n , &m)){ for(int i=1 ; i<=n ; i++){ scanf("%d" , &a[i]) ; } build(1 , 1 , n ) ; for(int i=1 ; i<=m ; i++){ scanf(" %c" , &ch) ; scanf("%d%d" , &x , &y) ; if(ch == ‘Q‘){ printf("%d\n" , query(1 ,x , y )) ; } if(ch == ‘U‘){ update(1 , x , y ) ; } cout<<1<<endl ; } } return 0 ; }
以上是关于(线段树) 单点更新,区间查询最值的主要内容,如果未能解决你的问题,请参考以下文章
HDU 1754 I Hate It(线段树之单点更新 区间最值查询)
ACM-ICPC国际大学生程序设计竞赛北京赛区(2017)网络赛 hihocoder #1586 : Minimum-区间查询最值求区间两数最小乘积+单点更新-线段树(结构体版)