5 6 1 2 3 4 5 Q 1 5 U 3 6 Q 3 4 Q 4 5 U 2 9 Q 1 5
5 6 5 9HintHuge input,the C function scanf() will work better than cin
#include <iostream> #include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> using namespace std; const int maxn=200010; int Max[maxn<<2]; void pushup(int root) { Max[root]=max(Max[root<<1],Max[root<<1|1]); } /*先建好线段树*/ void build(int root,int L,int R) { if(L==R){ //L==R时说明就一个点,输入跳出即可 scanf("%d",&Max[root]); return; } int mid=(L+R)>>1; build(root<<1,L,mid);//往左边建树 build(root<<1|1,mid+1,R);//往右边建树 pushup(root); //回溯父节点 } /*单点更新,i点的值更新为v*/ void update(int root,int L,int R,int i,int v) { if(L==R){ //L==R说明是此点没有子节点,把该点值赋值为v Max[root]=v; return; } int mid=(L+R)>>1; if(i<=mid)update(root<<1,L,mid,i,v); else update(root<<1|1,mid+1,R,i,v); pushup(root);//把此点的值更新为子节点的最大值 } /*区间求最值*/ int query(int root,int L,int R,int s,int e) { if(s==L&&e==R) //子区间和大区间相等 输出该点的值 { return Max[root]; } int mid=(L+R)>>1; int res=0; if(e<=mid) res=max(res,query(root<<1,L,mid,s,e)); //查询区间在中点左边 else if(s>mid) res=max(res,query(root<<1|1,mid+1,R,s,e));//查询区间在中点右边 else //中点在查询区间里面 { res=max(res,query(root<<1,L,mid,s,mid)); res=max(res,query(root<<1|1,mid+1,R,mid+1,e)); } return res; } int main() { int N,M,a,b; char c[5]; while(scanf("%d%d",&N,&M)!=EOF) { build(1,1,N); while(M--) { scanf("%s%d%d",c,&a,&b); if(c[0]=='Q') printf("%d\n",query(1,1,N,a,b)); else if(c[0]=='U') update(1,1,N,a,b); } } return 0; }