• HDU


    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

    解题思路:本题可以想到三种方法,暴力, 线段树, 树状数组。暴力的话复杂度为O(n^2),显然会超时。由于我现在还不会线段树,所以就只能树状数组了吧233
    这道题树状数组有些不同,以前都是对点更新找区间,这个是对区间更新找点,那么具体怎么做呢,首先要理解树状数组的c[]数组每个元素代表的是一段区间的值,我们把区间抽象成点,Sum(i)可以表示第i个气球被涂色的次数(画张图就可以理解),比如我们要涂色x~y区间的气球,那么我们先对x进行+1更新操作,相当于[x,MaxN]的气球被涂色一次,但由于我们只涂了x~y区间的气球,y+1及其以后的气球应该都没有涂色,那么我们把y+1再进行一次-1的更新操作就可以了,相当于[y+1,MaxN]的气球这次没有被涂色。这样进行操作始终保证了Sum(i)是第i个气球被涂色的次数。

    代码:
     1 #include<cstdlib>
     2 #include<cstdio>
     3 #include<cmath>
     4 #include<cstring>
     5 #include<string>
     6 #include<iostream>
     7 #include<algorithm>
     8 #include<map>
     9 #include<vector>
    10 using namespace std;
    11 const int MaxN = 1e5;
    12 
    13 int n;
    14 int num[MaxN+5], c[MaxN+5];
    15 
    16 int lowbit(int x)
    17 {
    18     return x&(-x);
    19 }
    20 
    21 void Add(int x, int y)
    22 {
    23     for(int i = x;i <= n;i += lowbit(i))
    24     {
    25         c[i] += y;
    26     }
    27 }
    28 
    29 int Sum(int x)
    30 {
    31     int ans = 0;
    32     for(int i = x;i > 0;i -= lowbit(i))
    33     {
    34         ans += c[i];
    35     }
    36     return ans;
    37 }
    38 
    39 
    40 int main()
    41 {
    42     int a, b;
    43     while(cin >> n && n)
    44     {
    45         memset(num, 0, sizeof(num));
    46         memset(c, 0, sizeof(c));
    47         for(int i = 1;i <= n;i++)
    48         {
    49             cin >> a >> b;
    50             Add(a, 1);
    51             Add(b + 1, -1);
    52         }
    53         printf("%d", Sum(1));
    54         for(int i = 2;i <= n;i++)
    55         {
    56             printf(" %d", Sum(i));
    57         }
    58         printf("
    ");
    59     }
    60     return 0;
    61 }
    
    
    

     
  • 相关阅读:
    day03 bs4解析库
    day02—selenium库
    day01爬虫三部曲
    IIC SPI UART通信方式的区别
    五大类程序设计模式
    套接字编程基础
    主机字节序和网络字节序转换
    位运算
    ARM体系结构的特点
    static关键字的作用
  • 原文地址:https://www.cnblogs.com/Lightfall/p/9307780.html
Copyright © 2020-2023  润新知