//这次换了种写法写线段树,加深了自己的理解
//6091831 2012-06-22 19:09:25 Accepted 1754 1234MS 8180K 1358 B C++ chen
#include<iostream>
using namespace std;
int n;
//表示某个节点的左右
int lef[200000*4];
int righ[200000*4];
//表示左儿子和右儿子的编号
int lson[200000*4];
int rson[200000*4];
int sum[200000*4];
char ch;
int Max(int a,int b){
return a>b?a:b;
}
//刚开始的写法是先定义全局变量p,q
//else if(b-a>0){
// p=n+1;
// lson[v]=p
// build(a,(a+b)/2);
// q=n+1;
// rson[v]=q;
// build((a+b)/2+1,b);
// sum[v]=Max(sum[p],sum[q]);
//}
//这样写的话会出错,我现在还想不明白什么原因
//创建线段树
void build(int a,int b){
n++;
int v=n;
lef[v]=a;
righ[v]=b;
if(a==b){
scanf("%d",&sum[v]);
return;
}
else if(b-a>0){
lson[v]=n+1;
build(a,(a+b)/2);
rson[v]=n+1;
build((a+b)/2+1,b);
sum[v]=Max(sum[lson[v]],sum[rson[v]]);
}
}
//询问【a,b】中【c,d】的最大值
int query(int a,int b,int root){
if(a<=lef[root]&&b>=righ[root]){
return sum[root];
}
int res=0;
int mid=(lef[root]+righ[root])/2;
//这儿一定要加上等号,因为这儿的划分是【1,2】划分为【1,1】和【2,2】
//比如说要寻找1,此时mid=1,如果不加上等号的话,则会在rson中寻找也就是【2,2】中寻找,这是找不到的
if(a<=mid)
res=Max(res,query(a,b,lson[root]));
if(b>mid)
res=Max(res,query(a,b,rson[root]));
return res;
}
//更新,不过这只是单点更新
void update(int a,int add,int root){
if(lef[root]==righ[root]){
sum[root]=add;
return;
}
int mid=(lef[root]+righ[root])/2;
if(a<=mid)
update(a,add,lson[root]);
else
update(a,add,rson[root]);
sum[root]=Max(sum[lson[root]],sum[rson[root]]);
}
int N,M,c,d;
int main(){
while(scanf("%d%d",&N,&M)!=EOF){
n=0;
build(1,N);
while(M--){
cin>>ch>>c>>d;
if(ch=='Q')
cout<<query(c,d,1)<<endl;
if(ch=='U')
update(c,d,1);
}
}
return 0;
}
hdu 1754 线段树
最新推荐文章于 2020-03-22 19:32:05 发布