zoukankan      html  css  js  c++  java
  • 华为笔试题 最高分是多少(线段树)

    老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.


    输入描述:
    输入包括多组测试数据。
    每组输入第一行是两个正整数N和M(0 < N <= 30000,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。

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

    输入例子1:
    5 7
    1 2 3 4 5
    Q 1 5
    U 3 6
    Q 3 4
    Q 4 5
    U 4 5
    U 2 9
    Q 1 5
    

    输出例子1:
    5
    6
    5
    9
    
    直接暴力肯定不行,也不能体现水准。。。。
    采用线段树
    单点更新,区间最大值查询的线段树。。。
    坑点:查询的时候给的A,B有可能是A>B,所以需要判断一下!

    #include<bits/stdc++.h>
    using namespace std;
    #define max_v 30005
    #define INF 999999
    #define me(a,x) memset(a,x,sizeof(a))
    typedef long long LL;
    
    struct node
    {
        int l,r,maxv;
    }tree[max_v<<2];
    
    int a[max_v];//存值
    
    int build(int l,int r,int k)//从点k开始 建树
    {
        tree[k].l=l;
        tree[k].r=r;
        if(l==r)//叶子节点
        {
            return tree[k].maxv=a[l];
        }
    
        int mid=(l+r)>>1;
        int x=build(l,mid,k<<1);
        int y=build(mid+1,r,k<<1|1);
    
        return tree[k].maxv=max(x,y);//更新区间最大值
    }
    
    int update(int v,int k,int w)//从点k开始 找到第v个值的位置将值改为w
    {
        if(tree[k].l>v||tree[k].r<v)//第v个值不在这个区间
        {
            return tree[k].maxv;
        }
        if(tree[k].l==v&&tree[k].r==v)//找到第v个值的位置
        {
            return tree[k].maxv=w;
        }
    
        int x=update(v,k<<1,w);
        int y=update(v,k<<1|1,w);
    
        return tree[k].maxv=max(x,y);
    }
    
    int getmax(int l,int r,int k)//从k开始 在第l个值和第r个值中间寻找最大值
    {
        if(tree[k].l>r||tree[k].r<l)
        {
            return 0;
        }
        if(tree[k].l>=l&&tree[k].r<=r)
        {
            return tree[k].maxv;
        }
    
        int x=getmax(l,r,k<<1);
        int y=getmax(l,r,k<<1|1);
    
        return max(x,y);
    }
    
    int main()
    {
        int n,m;
        while(~scanf("%d %d",&n,&m))
        {
            me(tree,0);
            for(int i=1;i<=n;i++)
                scanf("%d",&a[i]);//初始成绩
            char str[10];
            build(1,n,1);//1到n区间建树 1是根
            for(int i=1;i<=m;i++)
            {
                scanf("%s",str);
                if(str[0]=='Q')
                {
                    int l,r;
                    scanf("%d %d",&l,&r);
                    int x=max(l,r);
                    int y=min(l,r);//特判一下,确定大小关系
                    cout<<getmax(y,x,1)<<endl;
                }else if(str[0]=='U')
                {
                    int id,v;
                    cin>>id>>v;
                    a[id]=v;
                    update(id,1,v);
                }
            }
        }
        return 0;
    }


  • 相关阅读:
    002-Linux下防火墙相关命令操作
    001-网卡配置
    vs2012中自带IIS如何让其他电脑访问
    001-Mono for android在vs2012中发布设置
    小知识:utf-8和utf8mb4字符集
    Maven 模块化开发
    JUnit 单元测试
    解决8080端口占用问题
    (三)Tomcat服务器 -------JavaWeb的学习之路
    (一)走进JavaWeb的世界 -------JavaWeb的学习之路
  • 原文地址:https://www.cnblogs.com/yinbiao/p/10504737.html
Copyright © 2011-2022 走看看