zoukankan      html  css  js  c++  java
  • HDU 1556 Color the ball

    Problem Description
    N个气球排成一排,从左到右依次编 号为1,2,3....N.每次给定2个整数a b(a <= b),lele便为骑上他的“小飞鸽"牌电动车从气球a开始到气球b依次给每个气球涂一次颜色。但是N次以后lele已经忘记了第I个气球已经涂过几次颜 色了,你能帮他算出每个气球被涂过几次颜色吗?

     

    Input
    每个测试实例第一行为一个整数N,(N <= 100000).接下来的N行,每行包括2个整数a b(1 <= a <= b <= N)。
    当N = 0,输入结束。


    Output
    每个测试实例输出一行,包括N个整数,第I个数代表第I个气球总共被涂色的次数。


    Sample Input
    3
    1 1
    2 2
    3 3
    3
    1 1
    1 2
    1 3
    0


    Sample Output
    1 1 1
    3 2 1

       

            这是一道典型的一维树状数组的变形,普通的一维树状数组的用途是:单点更新,区间求值。而这道题的则是用到树状数组的另一个用途:区间更新,单点求值。原理如下:

          假设原始数组的各个元素为a[1] , a[2] ,…… a[n] ,  那么 d[n] = a[1] + a[2] + …… + a[n] 求的就是前n项和,这就是树状数组的第一个用途:单点更新,区间求和。 

           然后,稍微做些改动,假设原始数组的各个元素为a[1] - 0 , a[2] - a[1] , a[3] - a[2] ,……,a[n] - a[n - 1] , 那么此时的前n项和 d[n] = a[n] ,也就是说,现在原始数组的前n项和d[n]  就等于单点的值a[n] 了 ,大家看到这里是不是就有些明白了呢?

           接着,如果你想时区间[  a[m] …… a[n]  ] 中的所有值都 + Val ,那么只需将原始数组的第m项 (a[m] - a[m - 1] )  加上 Val  , 和将第n + 1项 (a[n + 1] - a[n])  减去 Val 就可以了, 这样当 m <= i <= n 时 ,

           数列的前 i 项和:

           d[i] = (a[1] - 0) + (a[2] - a[1]) + (a[3] - a[2]) + …… + (a[m] - a[m - 1] + val) + (a[m + 1] - a[m]) + …… + (a[i] - a[i - 1] )  = a[i]  + val 。  

           同理当 i > n 时 ,d[i] 等于原来的 a[i]  。看到这里,大家是不是就豁然开朗啦。注意一点,这里a[1] …… a[n] 的初始值均为0 !! 

     1 #include<iostream>
     2 #include<cstring>
     3 #include<string>
     4 #include<cstdio>
     5 #include<cmath>
     6 #include<algorithm>
     7 #include<queue>
     8 using namespace std ;
     9 const int MAXN = 1e5 + 5 ;
    10 int C[MAXN] ;
    11 int n ;
    12 int lowbit (int x)
    13 {
    14     return x & -x ;
    15 }
    16 void add(int x , int d)
    17 {
    18     while(x <= n)
    19     {
    20         C[x] += d ;
    21         x += lowbit(x) ;
    22     }
    23 }
    24 int sum(int x)
    25 {
    26     int sumt = 0 ;
    27     while (x > 0)
    28     {
    29         sumt += C[x] ;
    30         x -= lowbit(x) ;
    31     }
    32     return sumt ;
    33 }
    34 int main()
    35 {
    36     while (scanf("%d" , &n) != EOF)
    37     {
    38         if(n == 0 )
    39             break ;
    40         memset(C , 0 , sizeof(C)) ;
    41         int t = n ;
    42         int i ;
    43         while ( t-- )
    44         {
    45             int a , b ;
    46             scanf("%d%d", &a , &b) ;
    47             add(a , + 1) ;
    48             add(b + 1 , -1) ;
    49         }
    50         for(i = 1 ; i <= n ; i ++)
    51         {
    52             printf("%d" , sum(i)) ;
    53             if(i < n)
    54                 printf(" ") ;
    55         }
    56         puts("") ;
    57     }
    58     return 0 ;
    59 }
    随便写写。一点学习心得。。。--如果本文章没有注明转载则为原创文章,可以随意复制发表,但请注明出处与作者
  • 相关阅读:
    Asp.net MVC 3 RTM 源代码中单元测试帮助类
    CSharp扩展方法应用之获取特性
    Asp.net MVC中防止HttpPost重复提交
    JQuery实现倒计划按钮
    JQuery防止退格键网页后退
    .net中用Action等委托向外传递参数
    linux shell 用sed命令在文本的行尾或行首添加字符
    MongoDB分片中片键的选择
    Mongodb的Replica Sets + Sharding架构
    Mongodb数据分片的维护
  • 原文地址:https://www.cnblogs.com/ganhang-acm/p/3865123.html
Copyright © 2011-2022 走看看