这题最大节点数小于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如有不当之处欢迎指出!#include #include 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