HDU 1754 I Hate It

题解:线段树单点更新区间求极值。

#include <cstdio>
#include <algorithm>
using namespace std;
int a,b,q[200005],t[1200000];
void build(int l,int r,int x){
    int mid=(l+r)>>1;
    if(l==r){t[x]=q[mid];return;}
    build(l,mid,x<<1);
    build(mid+1,r,x<<1|1);
    t[x]=max(t[x<<1],t[x<<1|1]);
}
int query(int l,int r,int x){
    if(a<=l&&b>=r)return t[x];
    else{
        int mid=(l+r)>>1;
        if(b<=mid)return query(l,mid,x<<1);
        else if(a>mid)return query(mid+1,r,x<<1|1);
        else return max(query(l,mid,x<<1),query(mid+1,r,x<<1|1));
    }
}
void modify(int l,int r,int x){
    if(l==r){t[x]=b;return;}
    int mid=(l+r)>>1;
    if(a<=mid)modify(l,mid,x<<1),t[x]=max(t[x<<1],t[x<<1|1]);
    else{modify(mid+1,r,x<<1|1),t[x]=max(t[x<<1],t[x<<1|1]);}
}
int main(){
    int m,n; char op[3];
    while(~scanf("%d%d",&n,&m)){
        for(int i=1;i<=n;i++)scanf("%d",&q[i]);
        build(1,n,1);
        while(m--){
            scanf("%s%d%d",&op,&a,&b);
            if(op[0]=='Q')printf("%d\n",query(1,n,1));
            else modify(1,n,1);
        }
    }
    return 0;
}

当然分块处理也可以过

#include <cstdio>
#include <algorithm>
using namespace std;
char op[6];
int st[200005],en[200005],p[2000],i,size,block,a[200005],m,n,pos[200005],x,y;
int main(){
    while(~scanf("%d%d",&n,&m)){
        size=0;
        while(size*size<n)size++;pos[n]=(n-1)/size+1;
        for(int i=0;i<=size;i++)p[i]=-2147400000;
        for(block=pos[n],i=1;i<=block;i++)en[i-1]=(st[i]=size*(i-1)+1)-1;en[block]=n;
        for(i=1;i<=n;i++)scanf("%d",&a[i]),pos[i]=(i-1)/size+1,p[pos[i]]=max(p[pos[i]],a[i]);
        while(m--){
            scanf("%s%d%d",op,&x,&y);
            if(op[0]=='U'){
                int k=pos[x];
                p[k]=y; a[x]=y;
                for(int i=st[k];i<=en[k];i++)if(a[i]>p[k])p[k]=a[i];
            }
            if(op[0]=='Q'){
                int ans=-2147400000;
                if(pos[x]==pos[y]){
                    for(int i=x;i<=y;i++)ans=max(ans,a[i]);
                }else{
                    for(int i=x;i<=en[pos[x]];i++)ans=max(ans,a[i]);
                    for(int i=st[pos[y]];i<=y;i++)ans=max(ans,a[i]);
                    for(int i=pos[x]+1;i<pos[y];i++)ans=max(ans,p[i]);
                }
                printf("%d\n",ans);
            }
        }
    }return 0;
}

posted @ 2014-08-14 09:48  forever97  阅读(129)  评论(0编辑  收藏  举报