HDOJ 1754 I Hate It(线段树入门)

来源:互联网 发布:c语言小游戏编程 编辑:程序博客网 时间:2024/06/07 01:32

这是一道线段树的简单入门题,查找一段区间的最大值。用到的操作有build,update,query操作。我开始写这道题的时候总是超时,要注意两个地方,第一:如果输入Q或者U的时候,用的字符输入,必须加getchar(),这里会超时,如果用字符串貌似不用加。第二,查询操作的时候,最好不用Max的宏定义,如果 return  Max(query(l,r,2*rt),query(l,r,2*rt+1));也会超时。这和宏定义的Max的执行有关,会增加query操作的次数。

#include <iostream>
#include <stdio.h>
#include <string.h>
#define INF 1000000
using namespace std;

struct tree
{
    int l;
    int r;
    int max;
    //int mid;
} T[800006];
int Max(int a,int b)
{
    return a>b ? a:b;
}
void build(int l,int r,int rt)
{
    T[rt].l=l;
    T[rt].r=r;
    if(l==r)return;
       //T[rt].mid=(l+r)/2;
       int mid=(l+r)/2;
    build(l,mid,2*rt);
    build(mid+1,r,2*rt+1);
}


void update(int l,int r,int rt,int val)
{
    if(T[rt].l==l&&T[rt].r==r)
    {
        T[rt].max=val;
        return;
    }
    if(l>T[rt].r||r<T[rt].l)//不在范围内
    {
        return;
    }
    update(l,r,rt*2,val);
    update(l,r,rt*2+1,val);
    T[rt].max=Max(T[rt*2].max,T[rt*2+1].max);
}
int query(int l,int r,int rt)
{
    if(l<=T[rt].l&&r>=T[rt].r)
    {
        return T[rt].max;
    }
    if(l>T[rt].r||r<T[rt].l)//不在范围内
    {
        return -INF;
    }
    int aa=query(l,r,2*rt);
    int bb=query(l,r,2*rt+1);
     if(aa>bb)
        return aa;
     else return bb;


}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(T,0,sizeof(T));
        build(1,n,1);
        for(int i=1; i<=n; i++)
        {
            int x;
            scanf("%d",&x);
            update(i,i,1,x);
        }
        char c;
        int a,b;
        int ans=0;
        while(m--)
        {
            getchar();//attention
            scanf("%c",&c);
            scanf("%d%d",&a,&b);
            if(c=='Q')
            {
                ans=query(a,b,1);
                printf("%d\n",ans);
            }
            if(c=='U')
            {
                update(a,a,1,b);
            }
        }
    }
    return 0;
}


0 0