• HDU 1754 I Hate It(线段树+单点更新)


    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
     
    注:这是一道线段树的入门题,主要了解其基本的操作。
     
     1 #include <cstdio>
     2 #include <cmath>
     3 #include <cstring>
     4 #include <iostream>
     5 #include <algorithm>
     6 using namespace std;
     7 const int MAXN = 200005;
     8 struct data
     9 {
    10     int left, right, Max;
    11 } tree[3*MAXN];
    12 int score[MAXN];
    13 void pushUp(int node)
    14 {
    15     tree[node].Max = max(tree[2*node].Max, tree[2*node+1].Max);
    16 }
    17 void build(int left, int right, int node)   //构建线段树
    18 {
    19     //当前节点所表示的区间  
    20     tree[node].left = left;
    21     tree[node].right = right; 
    22     //左右区间相同,则此节点为叶子,Max 应储存对应某个学生的值
    23     if (left == right){
    24         tree[node].Max = score[left];
    25         return;
    26     }
    27     //递归建立左右子树
    28     int mid = left + (right - left) / 2;
    29     build(left, mid, 2*node);
    30     build(mid+1, right, 2*node+1);
    31     //从子树中获得最大值
    32     pushUp(node);
    33 }
    34 int query(int left, int right, int node)    //查询区间[left,right]的Max值
    35 {
    36     //所查区间不在范围内
    37     if (tree[node].left > right || tree[node].right < left)
    38         return 0;
    39     //所查区间包含当前节点所管理的区间
    40     if (left <= tree[node].left && tree[node].right <= right)  
    41         return tree[node].Max;
    42     int mid = (tree[node].left + tree[node].right) / 2;
    43     //所查区间与当前节点所管理的区间有部分相交
    44     if (right <= mid)
    45         return query(left, right, 2*node);
    46     else if (left > mid)
    47         return query(left, right, 2*node+1);
    48     else
    49         return max(query(left, right, 2*node), query(left, right, 2*node+1));
    50 }
    51 void Updata(int pos, int val, int node)     //更新pos点的值
    52 {
    53     //更新当前节点的Max值
    54     tree[node].Max = max(val, tree[node].Max);
    55     //pos点为叶子节点
    56     if (tree[node].left == pos && tree[node].right == pos){
    57         tree[node].Max = val;
    58         return;
    59     }
    60     if (pos <= tree[2*node].right)
    61         Updata(pos, val, 2*node);
    62     else
    63         Updata(pos, val, 2*node+1);
    64 }
    65 int main()
    66 {
    67     int n, m;
    68     while (~scanf("%d %d", &n, &m)){
    69         for (int i=1; i<=n; i++)
    70             scanf("%d", &score[i]);
    71         build(1, n, 1);
    72         char c;
    73         int a, b;
    74         for (int i=1; i<=m; i++){
    75             getchar();
    76             scanf("%c %d %d", &c, &a, &b);
    77             if (c == 'U')
    78                 Updata(a, b, 1);
    79             else
    80                 printf("%d
    ", query(a, b, 1));
    81         }
    82     }
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    JavaScript基础学习篇
    js,html,css注释大集合
    JS中的专业术语
    BFC给我的帮助以及对hasLayout的认识
    框架
    PHP echo和print语句
    PHP变量
    PHP语法
    PHP入门
    SQLite学习网址
  • 原文地址:https://www.cnblogs.com/hgfblog/p/4682200.html
Copyright © 2020-2023  润新知