• P1531 I Hate It 题解


    旅行传送门:https://www.luogu.com.cn/problem/P1531

    题目背景

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

    题目描述

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

    输入格式

    第一行,有两个正整数 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'的时候,表示这是一条更新操作,如果当前A学生的成绩低于B,则把ID为A的学生的成绩更改为B,否则不改动。

    输出格式

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

    输入输出样例

    输入 #1
    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
    输出 #1
    5
    6
    5
    9

    解题思路

    涉及单点修改和区间查询的水题,甚至都不需要打LazyTag,稍稍改改模板就能过(然而一开始却因为用scanf("%c%*c",&ch)读入询问信息死活a不了,最后还得老老实实用char数组orz)。

    AC代码

      1 #include <bits/stdc++.h>
      2 #define FOR(i, j, k) for (int i = (j); i <= (k); i++)
      3 #define MAXN 200000 + 5
      4 
      5 typedef long long ll;
      6 
      7 ll n, m, a[MAXN];
      8 char ch[2];
      9 
     10 struct node
     11 {
     12     ll l, r, max;
     13 } tree[MAXN << 2];
     14 
     15 ll read()
     16 {
     17     ll x = 0, f = 1;
     18     char ch = getchar();
     19     while (ch < '0' || ch > '9')
     20     {
     21         if (ch == '-')
     22             f = -1;
     23         ch = getchar();
     24     }
     25     while (ch >= '0' && ch <= '9')
     26     {
     27         x = x * 10 + ch - '0';
     28         ch = getchar();
     29     }
     30     return x * f;
     31 }
     32 
     33 void build(ll k, ll l, ll r)
     34 {
     35     tree[k].l = l, tree[k].r = r;
     36 
     37     if (l == r)
     38     {
     39         tree[k].max = a[l];
     40         return;
     41     }
     42 
     43     ll mid = (l + r) >> 1;
     44     build(k << 1, l, mid);
     45     build(k << 1 | 1, mid + 1, r);
     46     tree[k].max = std::max(tree[k << 1].max, tree[k << 1 | 1].max);
     47 }
     48 
     49 //区间修改的函数模板,实现单点修改只需向左右区间的端点传入相同的值即可
     50 void update(ll k, ll l, ll r, ll x)
     51 {
     52     if (tree[k].l == l && tree[k].r == r)
     53     {
     54         tree[k].max = std::max(tree[k].max, x);
     55         return;
     56     }
     57 
     58     ll mid = (tree[k].l + tree[k].r) >> 1;
     59 
     60     if (r <= mid)
     61         update(k << 1, l, r, x);
     62     else if (l > mid)
     63         update(k << 1 | 1, l, r, x);
     64     else
     65         update(k << 1, l, mid, x), update(k << 1 | 1, mid + 1, r, x);
     66 
     67     tree[k].max = std::max(tree[k << 1].max, tree[k << 1 | 1].max);
     68 }
     69 
     70 ll query(ll k, ll l, ll r)
     71 {
     72     if (tree[k].l == l && tree[k].r == r)
     73         return tree[k].max;
     74 
     75     ll mid = (tree[k].l + tree[k].r) >> 1;
     76 
     77     if (r <= mid)
     78         return query(k << 1, l, r);
     79     else if (l > mid)
     80         return query(k << 1 | 1, l, r);
     81     else
     82         return std::max(query(k << 1, l, mid), query(k << 1 | 1, mid + 1, r));
     83 }
     84 
     85 int main(int argc, char const *argv[])
     86 {
     87     n = read(), m = read();
     88 
     89     FOR(i, 1, n)
     90     a[i] = read();
     91 
     92     build(1, 1, n);
     93 
     94     while (m--)
     95     {
     96         scanf("%s", ch);
     97 
     98         if (ch[0] == 'Q')
     99         {
    100             ll a = read(), b = read();
    101             printf("%lld\n", query(1, a, b));
    102         }
    103         else if (ch[0] == 'U')
    104         {
    105             ll a = read(), b = read();
    106             update(1, a, a, b);
    107         }
    108     }
    109 
    110     return 0;
    111 }
    View Code
  • 相关阅读:
    JAVA选择结构
    JAVA关系运算符
    初识JAVA
    Java变量
    CSS
    HTML表单
    Dao层步骤
    JDBC
    集合框架
    使用log4j
  • 原文地址:https://www.cnblogs.com/Foreign/p/14583687.html
Copyright © 2020-2023  润新知