对于区间的值进行修改与查询最大,采用线段树解决。用一个变量来记录某个区间的最大值,同时每次更新后,需要递归回调每个区间的子区间的最大值。用于更新父节点的最大值。程序如下:
/*
ID: csuchenan
PROG: hduoj 1754 I hate it
LANG: C++
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define max(a , b) (a) > (b) ? (a) : (b)
#define MAXN 200005
#define MY_MAX -1
struct Node{
int left ;
int right ;
int nmax ;
}node[MAXN * 4] ;
void build(int left , int right , int layer) ;
void query(int left , int right , int layer , int &nmax) ;
void update(int pos , int nval , int layer) ;
void insert(int pos , int nval , int layer) ;
int n ;
int m ;
void work() ;
int main(int argc , char * argv[]){
while(scanf("%d %d" , &n , &m)!=EOF)
work() ;
return 0 ;
}
void work(){
//build the tree
build(1 , n , 1) ;
int i ;
int data ;
i = 1 ;
while(i <= n){
scanf("%d" , &data) ;
//insert the data into the tree
insert(i , data , 1) ;
i++ ;
}
char c ;
i = 0 ;
int p ;
int q ;
int nmax ;
while(i < m){
getchar() ;
scanf("%c %d %d" , &c , &p , &q) ;
if(c == 'Q'){
nmax = MY_MAX ;
query(p , q , 1 , nmax) ;
printf("%d\n" , nmax) ;
}
else{
update(p , q , 1) ;
}
i ++ ;
}
}
void build(int left , int right , int layer ){
node[layer].left = left ;
node[layer].right = right ;
node[layer].nmax = MY_MAX ;
if(left == right){
return ;
}
int mid = (left + right) / 2 ;
int llayer = layer * 2 ;
int rlayer = layer * 2 + 1 ;
build(left , mid , llayer) ;
build(mid + 1 , right , rlayer) ;
return ;
}
void insert(int pos , int nval , int layer){
if(node[layer].nmax < nval){
node[layer].nmax = nval ;
}
if(pos == node[layer].left && pos == node[layer].right){
return ;
}
int mid = (node[layer].left + node[layer].right) / 2 ;
int nlayer ;
if(mid >= pos){
nlayer = layer * 2 ;
insert(pos , nval , nlayer) ;
return ;
}
nlayer = layer * 2 + 1 ;
insert(pos , nval , nlayer) ;
return ;
}
void update(int pos , int nval , int layer){
if(node[layer].left == pos && node[layer].right == pos){
node[layer].nmax = nval ;
return ;
}
int mid = (node[layer].left + node[layer].right) / 2 ;
int llayer ;
int rlayer ;
llayer = layer * 2 ;
rlayer = layer * 2 + 1 ;
if(pos <= mid){
update(pos , nval , llayer) ;
}
else{
update(pos , nval , rlayer) ;
}
node[layer].nmax = max(node[llayer].nmax , node[rlayer].nmax) ;
return ;
}
void query(int left , int right , int layer , int &nmax){
if(node[layer].left == left && node[layer].right == right){
nmax = max( node[layer].nmax , nmax );
return ;
}
int mid = (node[layer].left + node[layer].right) / 2 ;
int nlayer ;
if(right <= mid){
nlayer = layer * 2 ;
query(left , right , nlayer , nmax ) ;
return ;
}
if(left > mid){
nlayer = layer * 2 + 1 ;
query(left , right , nlayer , nmax) ;
return ;
}
nlayer = layer * 2 ;
query(left , mid , nlayer , nmax) ;
query(mid + 1 , right , nlayer + 1 , nmax) ;
return ;
}