• hdu 1166


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

    题意:给n个数字。对这n个数字有3种操作:1. add 2.sub 3.query。分别对应把某数增加或减少一个值和查询某[l,r]区间内所有值的和。

    mark:最基本的线段树or树状数组的应用。话说树状数组真是简洁啊!

    代码:

    线段树

     1 # include <stdio.h>
     2 # include <string.h>
     3 
     4 
     5 int n, tr[50010<<2] ;
     6 
     7 
     8 void add(int a, int b, int l, int r, int rt)
     9 {
    10     int m = (l+r)/2 ;
    11     tr[rt] += b;
    12     if (l == r) return;
    13     if (a <= m) add (a, b, l, m, rt*2) ;
    14     else add (a, b, m+1, r, rt*2+1) ;
    15 }
    16 
    17 
    18 int query (int a, int b, int l, int r, int rt)
    19 {
    20     int m, rtn ;
    21     if (l == a && r == b) return tr[rt] ;
    22     m = (l+r)/2 ;
    23     if (b <= m) return query(a, b, l, m, rt*2) ;
    24     if (a > m) return query (a, b, m+1, r, rt*2+1) ;
    25     return query(a, m, l, m, rt*2) + query (m+1, b, m+1, r, rt*2+1) ;
    26 }
    27 
    28 
    29 int main ()
    30 {
    31     int T, nCase = 1;
    32     int i, num, a, b ;
    33     char order[10] ;
    34     scanf ("%d", &T) ;
    35     while (T--)
    36     {
    37         memset (tr, 0, sizeof(tr)) ;
    38         printf ("Case %d:
    ", nCase++) ;
    39         scanf ("%d", &n) ;
    40         for (i = 1 ; i <= n ; i++)
    41             scanf ("%d", &num), add(i, num, 1, n, 1) ;
    42         while (1)
    43         {
    44             scanf ("%s", order) ;
    45             if (!strcmp(order, "End")) break ;
    46             scanf ("%d%d", &a, &b) ;
    47             if (!strcmp(order, "Query"))
    48                 printf ("%d
    ", query(a, b, 1, n, 1));
    49             else if (!strcmp(order, "Sub"))
    50                 add (a, -b, 1, n, 1) ;
    51             else add (a, b, 1, n, 1) ;
    52         }
    53     }
    54     return 0 ;
    55 }
    View Code

    树状数组

     1 # include <stdio.h>
     2 # include <string.h>
     3 
     4 
     5 int bit[50010] ;
     6 int n ;
     7 
     8 
     9 int lowbit (int x){return x & -x;}
    10 
    11 
    12 void add (int a, int b)
    13 {
    14     while (a <= n)
    15         bit[a] += b, a += lowbit(a);
    16 }
    17 
    18 
    19 int q(int a)
    20 {
    21     int ans = 0 ;
    22     while (a)
    23         ans += bit[a], a -= lowbit(a);
    24     return ans ;
    25 }
    26 
    27 
    28 int main ()
    29 {
    30     int T, i, nCase = 1, a, b ;
    31     char ord[10] ;
    32     scanf ("%d", &T) ;
    33     while (T--)
    34     {
    35         memset (bit, 0, sizeof(bit)) ;
    36         scanf ("%d", &n) ;
    37         for (i = 1 ; i <= n ; i++)
    38             scanf ("%d", &a), add (i, a) ;
    39         printf ("Case %d:
    ", nCase++) ;
    40         while (~scanf ("%s", ord) && strcmp(ord, "End"))
    41         {
    42             scanf ("%d%d", &a, &b) ;
    43             if (!strcmp(ord, "Query"))
    44                 printf ("%d
    ", q(b) - q(a-1)) ;
    45             else if (!strcmp(ord, "Sub"))
    46                 add (a, -b) ;
    47             else add (a, b) ;
    48         }
    49     }
    50     return 0 ;
    51 }
    View Code
  • 相关阅读:
    Java内存模型
    BigDecimal踩过的大坑
    Java开发小技巧
    多线程同步辅助工具类
    ReentrantLock中的公平锁与非公平锁
    ReentrantLock与synchronized的区别
    推荐一个Java设计模式写的很好的博客
    线程池ThreadPoolExecutor工作原理
    支付系统架构设计转载
    linux 部署脚本
  • 原文地址:https://www.cnblogs.com/lzsz1212/p/3456333.html
Copyright © 2020-2023  润新知