题目连接 http://acm.hust.edu.cn/vjudge/contest/121192#problem/E
这一题也是线段树的应用,和上一题类似,都是建树,更新,查询。但是这一题求的是最大值,所以上一题父区间时所有子区间的和应改为子区间的最大值。
#include<iostream> #include<cstdio> #include<algorithm> using namespace std; #define Max 200005 int n; int a[Max] ; int t[Max<<2]; void build(int l,int r,int pt)//建树 { if(l==r) { t[pt]=a[pt]; return ; } int mid=(l+r)>>1; t[pt]=-1; if(l<=mid) { build(l,mid,pt<<1); t[pt]=max(t[pt],t[pt<<1]);//此处根据题目变动 } if(r>mid) { build(mid+1,r,pt<<1|1); t[pt]=max(t[pt],t[pt<<1|1]); } void Update(int id,int ch,int l,int r,int pt )//更新 { if(l==r) { t[id]=ch; return ; } int mid=(r+l)>>1; if(mid>=id) Update(id,ch,l,mid,pt<<1); else Update(id,ch,mid+1,r,pt<<1|1); t[pt]=max(t[pt<<1],t[pt<<1|1]); } int Query(int x,int y,int pt,int l,int r)//查询 { if(x<=l&&y>=r) return t[pt]; int mid=(l+r)>>1; int tm1=-1,tm2=-1; if(x<=mid) tm1=Query(x,y,pt<<1,l,mid); if(y>mid) tm2=Query(x,y,pt<<1|1,mid+1,r); return max(tm1,tm2); } int main() { int n,m,x,y,id,ch,i; char c; while(scanf("%d%d",&n,&m)!=EOF) { for(i=1;i<=n;i++) cin>>a[i]; build(1,n,1); while(m--) { cin>>c; if(c=='Q') { cin>>x>>y; cout<<Query(x,y,1,1,n)<<endl; } if(c=='U') { cin>>id>>ch; Update(id,ch,1,n,1); } } } return 0; }