hdu 1754:I Hate It(线段树应用之:区间最值问题)

hdu 1754:I Hate It(线段树(树状数组)应用之:区间最值问题)


题目链接:hdu 1754


Problem Description


很多学校流行一种比较的习惯。老师们很喜欢询问,从某某到某某当中,分数最高的是多少。
这让很多学生很反感。

不管你喜不喜欢,现在需要你做的是,就是按照老师的要求,写一个程序,模拟老师的询问。当然,老师有时候需要更新某位同学的成绩。


Input


本题目包含多组测试,请处理到文件结束。
在每个测试的第一行,有两个正整数 N 和 M ( 0<N<=200000,0<M<5000 ),分别代表学生的数目和操作的数目。
学生ID编号分别从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩。
接下来有M行。每一行有一个字符 C (只取’Q’或’U’) ,和两个正整数A,B。
当C为’Q’的时候,表示这是一条询问操作,它询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少。
当C为’U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。


Output


对于每一次询问操作,在一行里面输出最高成绩。


Sample Input


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


Sample Output


5
6
5
9

Hint
Huge input,the C function scanf() will work better than cin

题解:线段树区间最值模板题之一:点修改,及区间查询

代码如下:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
using namespace std;
const int INF=0xffffff0;      //设一个最大值
const int maxn=200010;        //学生数目(即叶子结点数目)

/**结点结构*/
struct Node
{
    int L,R;
    int v;
};

Node tree[4*maxn];      //用数组代替指针表示线段树
int a[maxn];          //存放学生信息

int maxV=-INF;         //表示最大值

/**建立线段树,并附初值*/
void build_Tree(int root,int L,int R)
{
    tree[root].L=L;
    tree[root].R=R;
    if(L==R)
    {
        tree[root].v=a[L];
        return ;
    }

    int mid=(tree[root].L+tree[root].R)/2;

    /**向下直到叶子结点为止*/
    build_Tree(2*root,L,mid);
    build_Tree(2*root+1,mid+1,R);

    tree[root].v=max(tree[2*root].v,tree[2*root+1].v);     //回溯时获得左右孩子最大值

}

/**更新操作(即线段树维护)*/
void update(int root,int i,int v)
{
    if(tree[root].L==i&&tree[root].R==i)
    {
        tree[root].v=v;
        return ;
    }

    int mid=(tree[root].L+tree[root].R)/2;

    if(i<=mid)
        update(2*root,i,v);
    else
        update(2*root+1,i,v);

    tree[root].v=max(tree[2*root].v,tree[2*root+1].v);    //回溯获得左右孩子最大值
}

/**查询区间[s,e]中的最大值*/
void Query(int root,int s,int e)
{

    if(tree[root].L==s&&tree[root].R==e)
    {
        maxV=max(maxV,tree[root].v);
        return ;
    }
    int mid=(tree[root].L+tree[root].R)/2;

    /**区间过大*/
    if(e<=mid)
        Query(2*root,s,e);
    else if(s>mid)
        Query(2*root+1,s,e);
    else
    {
        Query(2*root,s,mid);
        Query(2*root+1,mid+1,e);
    }
}
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(tree,-INF,sizeof(tree));
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        build_Tree(1,1,n);

        char ch;          //表示是询问操作还是更新操作
        int a,b;     //如果是询问操作的话,则表示区间[a,b];如果是更新操作,则表示学生a成绩变为b
        for(int i=1;i<=m;i++)
        {
            getchar();
            scanf("%c",&ch);
            scanf("%d%d",&a,&b);

            if(ch=='Q')
            {
                maxV=-INF;
                Query(1,a,b);
                printf("%d\n",maxV);
            }
            else
                update(1,a,b);
        }
    }
    return 0;
}

题解二:树状数组求解

虽然我觉得这种最值问题,不像求和问题,树状数组处理似乎看上去并不怎么好,但是为了复习树状数组,还是用树状数组做了下:

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int a[200010];
int h[200010];
int n,m;
inline int lowbit(int x)
{
    return x&(-x);
}
void update(int x)
{
    int lx;
    while(x<=n)
    {
        h[x]=a[x];
        lx=lowbit(x);
        for(int i=1;i<lx;i<<=1)
            h[x]=max(h[x],h[x-i]);
        x+=lowbit(x);
    }
}
int query(int x,int y)
{
    int ans=0;
    while(y>=x)
    {
        ans=max(a[y],ans);
        y--;
        for(;y-lowbit(y)>=x;y-=lowbit(y))
            ans=max(h[y],ans);
    }
    return ans;
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        memset(a,0,sizeof(a));
        memset(h,0,sizeof(h));
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            update(i);
        }
        char ch;
        int x,y;
        while(m--)
        {
            getchar();
            scanf("%c",&ch);
            scanf("%d%d",&x,&y);
            if(ch=='U')
            {
                a[x]=y;
                update(x);
            }
            else
            {
                printf("%d\n",query(x,y));
            }
        }
    }
    return 0;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
东南亚位于我国倡导推进的“一带一路”海陆交汇地带,作为当今全球发展最为迅速的地区之一,近年来区域内生产总值实现了显著且稳定的增长。根据东盟主要经济体公布的最新数据,印度尼西亚2023年国内生产总值(GDP)增长5.05%;越南2023年经济增长5.05%;马来西亚2023年经济增速为3.7%;泰国2023年经济增长1.9%;新加坡2023年经济增长1.1%;柬埔寨2023年经济增速预计为5.6%。 东盟国家在“一带一路”沿线国家中的总体GDP经济规模、贸易总额与国外直接投资均为最大,因此有着举足轻重的地位和作用。当前,东盟与中国已互相成为双方最大的交易伙伴。中国-东盟贸易总额已从2013年的443亿元增长至 2023年合计超逾6.4万亿元,占中国外贸总值的15.4%。在过去20余年中,东盟国家不断在全球多变的格局里面临挑战并寻求机遇。2023东盟国家主要经济体受到国内消费、国外投资、货币政策、旅游业复苏、和大宗商品出口价企稳等方面的提振,经济显现出稳步增长态势和强韧性的潜能。 本调研报告旨在深度挖掘东南亚市场的增长潜力与发展机会,分析东南亚市场竞争态势、销售模式、客户偏好、整体市场营商环境,为国内企业出海开展业务提供客观参考意见。 本文核心内容: 市场空间:全球行业市场空间、东南亚市场发展空间。 竞争态势:全球份额,东南亚市场企业份额。 销售模式:东南亚市场销售模式、本地代理商 客户情况:东南亚本地客户及偏好分析 营商环境:东南亚营商环境分析 本文纳入的企业包括国外及印尼本土企业,以及相关上下游企业等,部分名单 QYResearch是全球知名的大型咨询公司,行业涵盖各高科技行业产业链细分市场,横跨如半导体产业链(半导体设备及零部件、半导体材料、集成电路、制造、封测、分立器件、传感器、光电器件)、光伏产业链(设备、硅料/硅片、电池片、组件、辅料支架、逆变器、电站终端)、新能源汽车产业链(动力电池及材料、电驱电控、汽车半导体/电子、整车、充电桩)、通信产业链(通信系统设备、终端设备、电子元器件、射频前端、光模块、4G/5G/6G、宽带、IoT、数字经济、AI)、先进材料产业链(金属材料、高分子材料、陶瓷材料、纳米材料等)、机械制造产业链(数控机床、工程机械、电气机械、3C自动化、工业机器人、激光、工控、无人机)、食品药品、医疗器械、农业等。邮箱:market@qyresearch.com

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值