• hdu 1754


    地址:http://acm.hdu.edu.cn/showproblem.php?pid=1754

    题意:给n个数字。m次操作,每次操作更新一个数字或者查询区间最大值。

    mark:典型线段树题。不过a的时候学了一下树状数组求区间最值。感觉对树状数组的理解又深刻了一点。不过这个更新不是O(lgn)而是O(lgn*lgn)的,比线段树慢!

    代码:

    线段树:

     1 # include <stdio.h>
     2 # include <string.h>
     3 
     4 
     5 #define max(a,b) (a>b?a:b)
     6 int n ;
     7 int tr[200010<<2] ;
     8 
     9 
    10 void u(int a, int b, int l, int r, int rt)
    11 {    
    12     int m = (l+r)/2 ;
    13     if (l == r) {
    14         tr[rt] = b;
    15         return;
    16     }
    17     if (a <= m) u(a, b, l, m, rt*2);
    18     else u(a, b, m+1, r, rt*2+1);
    19     tr[rt] = max(tr[rt*2], tr[rt*2+1]);
    20 }
    21 
    22 
    23 int q(int a, int b, int l, int r, int rt)
    24 {
    25     int m = (l + r) / 2, a1, a2 ;
    26     if (a == l && b == r) return tr[rt];
    27     if (b <= m) return q(a, b, l, m, rt*2) ;
    28     else if (a > m) return q(a, b, m+1, r, rt*2+1) ;
    29     a1 = q(a, m, l, m, rt*2), a2 = q(m+1, b, m+1, r, rt*2+1) ;
    30     return max(a1, a2) ;
    31 }
    32 
    33 
    34 int main ()
    35 {
    36     int m, i, a, b ;
    37     char op[5] ;
    38     
    39     while (~scanf ("%d%d", &n, &m))
    40     {
    41         //memset (tr, 0, sizeof(tr));
    42         for (i = 1 ; i <= n ; i++)
    43             scanf ("%d", &a), u(i, a, 1, n, 1);
    44         while (m--)
    45         {
    46             scanf ("%s %d %d", op, &a, &b) ;
    47             if (op[0] == 'U') u(a, b, 1, n, 1);
    48             else printf ("%d
    ", q(a, b, 1, n, 1)) ;
    49         }
    50     }
    51     return 0 ;
    52 }
    View Code

    树状数组(不加inline优化max函数的话会TLE!!!)

     1 # include <stdio.h>
     2 # include <string.h>
     3 
     4 
     5 int n, num[200010], tr[200010];
     6 int lowbit(int x){return x & -x;}
     7 inline int max(int a, int b){return a>b?a:b;}
     8 
     9 
    10 void u(int a, int b){
    11     int i, j;
    12     num[a] = b;
    13     for (i = a; i <= n; i+=lowbit(i))
    14     {
    15         tr[i] = num[i];
    16         for (j = 1; j < lowbit(i); j <<= 1)
    17             tr[i] = max(tr[i], tr[i-j]);
    18     }
    19 }
    20 
    21 
    22 int q(int a, int b){
    23     int i = b, ans = num[b];
    24     while (i >= a)
    25         if (i-lowbit(i)+1 >= a)
    26             ans = max(ans, tr[i]), i -= lowbit(i);
    27         else
    28             ans = max(ans, num[i]), i--;
    29     return ans;
    30 }
    31 
    32     
    33 int main ()
    34 {
    35     int a, b, i, m;
    36     char op[5];
    37     while (~scanf ("%d%d", &n, &m))
    38     {
    39         memset(tr, 0, sizeof(tr));
    40         for (i = 1; i <= n; i++)
    41             scanf ("%d", &a), u(i, a);
    42         while (m--)
    43         {
    44             scanf ("%s %d %d", op, &a, &b);
    45             if (op[0] == 'U') u(a, b);
    46             else printf ("%d
    ", q(a, b)) ;
    47         }
    48     }
    49     return 0 ;
    50 }
    View Code
  • 相关阅读:
    (C#基础) byte[] 之初始化, 赋值,转换。
    System.IO.IOException: The handle is invalid.
    .NET 自动内存管理(垃圾收集GC)
    Inconsistent accessibility
    有用的网址
    dw添加emmet
    行内标签,怎么取消两个标签中间的距离
    2016.6.2近日学习计划
    HTML5 input placeholder 颜色修改示例
    加入收藏和设为首页
  • 原文地址:https://www.cnblogs.com/lzsz1212/p/3456800.html
Copyright © 2020-2023  润新知