HDOJ 1754 线段树

次元传送门今天放假

题意:
求区间内最大值
会有单个修改
多CASE

分析:
线段树变形

代码实现

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;

struct Line{
    int a,b,Max;
    Line *left,*right;

    Line(){
        a=b=Max=0;
        left=right=NULL;
    }

    int Add(int v[],int l,int r){
        a=l,b=r;
        if(l+1==r)
            return Max=v[l];
        else{
            int mid=(l+r)>>1;
            if(left==NULL)
                left=new Line;
            if(right==NULL)
                right=new Line;
            Max=max(Max,left->Add(v,l,mid));
            Max=max(Max,right->Add(v,mid,r));
            return Max;
        }
    }

    int CalcMax(int l,int r){
        if(l>=r)
            return 0;
        if(a==l&&b==r)
            return Max;
        else{
            int mid=(a+b)>>1;
            return max(left->CalcMax(l,min(mid,r)),right->CalcMax(max(mid,l),r));
        }
    }

    int Change(int pos,int val){
        if(a==pos&&b==pos+1)
            Max=val;
        else{
            int mid=(a+b)>>1;
            if(pos<mid)
                Max=max(left->Change(pos,val),right->Max);
            else
                Max=max(left->Max,right->Change(pos,val));
        }
        return Max;
    }

    void Clear(void){
        if(left)left->Clear();
        if(right)right->Clear();
        Max=a=b=0;
    }

}Root;

const int N=200001;
int n,m,v[N];
char c;

int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        Root.Clear();
        for(int i=1;i<=n;i++)
            scanf("%d",&v[i]);
        Root.Add(v,1,n+1);
        for(int i=0,x,y;i<m;i++){
            cin>>c;
            cin>>x>>y;
            if(c=='Q')
                printf("%d\n",Root.CalcMax(x,y+1));
            else
                Root.Change(x,y);
        }
    }
    return 0;
}

后记
题目中说避免使用cin的鬼话无视就好
时间完全足够

By YOUSIKI

你可能感兴趣的:(HDOJ 1754 线段树)