#include

(线段树) 单点更新,区间查询最值

/* 单点更新,区间查询最值  */
/* 注意线段树的大小要比需要使用线段树的数据的个数 大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 ; }

 

posted @ 2017-10-21 00:35  0一叶0知秋0  阅读(161)  评论(0编辑  收藏  举报