hdu1754 线段树

         这题最大节点数小于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;
}

如有不当之处欢迎指出!


转载于:https://www.cnblogs.com/flyawayl/p/8305478.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值