这题最大节点数小于10^6,可以用数组存下,但是这题需要注意max的用法。
//return max(getAns(root<<1,l,mid,ll,mid),getAns((root<<1)+1,mid+1,r,mid+1,rr)); //一定不要这样写,会超时
int a= getAns(root<<1,l,mid,ll,mid);
int b=getAns((root<<1)+1,mid+1,r,mid+1,rr);
return max(a,b);
更新时需要自底向上更新,因为有可能被改变的值是当前最大值。
AC代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=2e5+5;
int tree[maxn*4];
void Build_tree(int l,int r,int cur){
if(l==r) {
scanf("%d",&tree[cur]);
return;
}
Build_tree(l,(l+r)/2,cur<<1);
Build_tree((l+r)/2+1,r,(cur<<1)+1);
tree[cur]=max(tree[cur<<1],tree[(cur<<1)+1]);
}
int num,score;
void Update(int l,int r,int cur){ //自下向上更新
if(l==r) {
tree[cur]=score;
return;
}
int mid=(l+r)/2;
if(num<=mid) Update(l,mid,cur*2);
else Update(mid+1,r,cur*2+1);
tree[cur]=max(tree[cur<<1],tree[(cur<<1)+1]);
}
int getAns(int root,int l,int r,int ll,int rr){
if(l==ll&&r==rr) return tree[root];
int mid=(ll+rr)/2;
if(r<=mid) return getAns(root<<1,l,r,ll,mid);
else if(l>=mid+1) return getAns((root<<1)+1,l,r,mid+1,rr);
else {
//return max(getAns(root<<1,l,mid,ll,mid),getAns((root<<1)+1,mid+1,r,mid+1,rr));
int a= getAns(root<<1,l,mid,ll,mid);
int b=getAns((root<<1)+1,mid+1,r,mid+1,rr);
return max(a,b);
}
}
int main(){
int n,m;
while(scanf("%d%d",&n,&m)==2){
//memset(tree,-1,sizeof(tree));
Build_tree(1,n,1);
getchar(); //接收换行符
char ch;
for(int i=0;i<m;++i){
scanf("%c%d%d",&ch,&num,&score);
getchar();
if(ch=='U') {
Update(1,n,1);
}
else printf("%d\n",getAns(1,num,score,1,n));
}
}
return 0;
}
如有不当之处欢迎指出!